Python算法详解:贪心算法

news2025/2/4 2:28:53

贪心算法(Greedy Algorithm)是一种通过选择当前最优解以期望达到全局最优解的算法思想。它在每一步选择时只考虑当前状态下的局部最优,而不关心全局问题的复杂性。这种算法简单高效,适用于某些特定问题,尤其是存在贪心选择性质最优子结构的问题。本文将从贪心算法的基础思想出发,结合Python代码,详细解析其应用与实现。

目录

贪心算法的核心思想

案例 1:活动选择问题

解题步骤:

Python 实现:

代码说明:

案例 2:哈夫曼编码

解题步骤:

Python 实现:

代码说明:

案例 3:最小零钱问题

解题步骤:

Python 实现:

代码说明:


贪心算法的核心思想

贪心算法的基本逻辑可以总结为:

  1. 贪心选择性质: 每一步选择当前的最优解,能够逐步形成问题的整体最优解。
  2. 最优子结构: 子问题的最优解可以递归地构成原问题的最优解。
  3. 不可回退: 贪心算法一旦作出选择,就不能回头修改之前的选择。

适用场景: 贪心算法通常适用于以下类型的问题:

  • 优化类问题(如最小化成本、最大化收益)。
  • 可以通过局部最优解递推到全局最优解的问题。

典型案例包括活动选择问题、最小生成树、哈夫曼编码等。


案例 1:活动选择问题

问题描述: 给定一组活动,每个活动有一个开始时间和结束时间。需要选择尽可能多的活动,且任意两个活动不能重叠。

解题步骤:
  1. 贪心选择: 按活动的结束时间从早到晚排序。
  2. 选择活动: 每次选择当前结束时间最早的活动,且该活动与前一个活动不冲突。
Python 实现:
# 活动选择问题的实现
def activity_selection(activities):
    # 按结束时间排序
    activities.sort(key=lambda x: x[1])

    selected = []
    last_end_time = 0

    for start, end in activities:
        if start >= last_end_time:
            selected.append((start, end))
            last_end_time = end

    return selected

# 测试数据
activities = [(1, 4), (3, 5), (0, 6), (5, 7), (3, 8), (5, 9), (6, 10), (8, 11), (8, 12), (2, 13), (12, 14)]
selected_activities = activity_selection(activities)
print("Selected activities:", selected_activities)
代码说明:
  1. 排序:
    • 按活动的结束时间排序,确保每次选择的活动与后续活动有最大可能的兼容性。
  2. 选择活动:
    • 遍历活动列表,选择开始时间大于等于上一个活动结束时间的活动。
  3. 时间复杂度:
    • 排序的时间复杂度为 ( O(nlogn) ),选择活动的复杂度为 ( O(n) )。
案例 2:哈夫曼编码

问题描述: 哈夫曼编码是一种数据压缩算法,用于构建最优前缀编码,使得高频字符使用较短的编码。

解题步骤:
  1. 贪心选择: 每次从当前权值最小的两个节点合并,形成新的节点。
  2. 重复步骤: 直到所有节点被合并为一棵哈夫曼树。
Python 实现:
import heapq

# 哈夫曼编码实现
def huffman_coding(frequencies):
    heap = [[weight, [symbol, ""]] for symbol, weight in frequencies.items()]
    heapq.heapify(heap)

    while len(heap) > 1:
        low1 = heapq.heappop(heap)
        low2 = heapq.heappop(heap)
        for pair in low1[1:]:
            pair[1] = '0' + pair[1]
        for pair in low2[1:]:
            pair[1] = '1' + pair[1]
        heapq.heappush(heap, [low1[0] + low2[0]] + low1[1:] + low2[1:])

    return sorted(heapq.heappop(heap)[1:], key=lambda p: (len(p[-1]), p))

# 测试数据
frequencies = {'A': 45, 'B': 13, 'C': 12, 'D': 16, 'E': 9, 'F': 5}
encoding = huffman_coding(frequencies)
print("Huffman Encoding:", encoding)
代码说明:
  1. 优先队列:
    • 使用 Python 的 heapq 构建最小堆,方便每次快速找到权值最小的两个节点。
  2. 合并节点:
    • 每次弹出两个最小节点,合并后重新压入堆中。
  3. 生成编码:
    • 在树中通过向左加 0,向右加 1 的方式生成编码。
  4. 时间复杂度:
    • 建堆和合并操作的时间复杂度为 ( O(nlogn) )。
案例 3:最小零钱问题

问题描述: 给定一组硬币面额和一个总金额,求最少需要多少硬币凑出该金额。

解题步骤:
  1. 贪心选择: 每次选择面额最大的硬币。
  2. 验证: 减去当前硬币面额后,继续选择直到总金额为 0。
Python 实现:
# 最小零钱问题的实现
def coin_change(coins, amount):
    coins.sort(reverse=True)  # 按面额从大到小排序
    count = 0

    for coin in coins:
        while amount >= coin:
            amount -= coin
            count += 1

    return count if amount == 0 else -1

# 测试数据
coins = [1, 2, 5, 10]
amount = 27
result = coin_change(coins, amount)
print("Minimum coins needed:", result)
代码说明:
  1. 排序:
    • 按面额从大到小排序,确保优先选择较大面额的硬币。
  2. 减金额:
    • 每次选择一个硬币,减少目标金额,直到目标为 0。
  3. 限制条件:
    • 贪心策略不一定适用于所有硬币组合。对于无法凑出的情况,返回 (-1)。

        贪心算法通过逐步选择局部最优解,简化了问题的求解过程。本文通过活动选择问题、哈夫曼编码和最小零钱问题的实例,详细讲解了贪心算法的应用场景和实现方式。掌握贪心思想后,读者可以灵活运用它解决各类优化问题,并理解其局限性。

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

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

相关文章

gesp(C++六级)(10)洛谷:P10722:[GESP202406 六级] 二叉树

gesp(C六级)(10)洛谷:P10722:[GESP202406 六级] 二叉树 题目描述 小杨有⼀棵包含 n n n 个节点的二叉树,且根节点的编号为 1 1 1。这棵二叉树任意⼀个节点要么是白色,要么是黑色。之后小杨会对这棵二叉树…

w186格障碍诊断系统spring boot设计与实现

🙊作者简介:多年一线开发工作经验,原创团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹赠送计算机毕业设计600个选题excel文…

Android Studio 正式版 10 周年回顾,承载 Androider 的峥嵘十年

Android Studio 1.0 宣发于 2014 年 12 月,而现在时间来到 2025 ,不知不觉间 Android Studio 已经陪伴 Androider 走过十年历程。 Android Studio 10 周年,也代表着了我的职业生涯也超十年,现在回想起来依然觉得「唏嘘」&#xff…

4 Hadoop 面试真题

4 Hadoop 面试真题 1. Apache Hadoop 3.0.02. HDFS 3.x 数据存储新特性-纠删码Hadoop面试真题 1. Apache Hadoop 3.0.0 Apache Hadoop 3.0.0在以前的主要发行版本(hadoop-2.x)上进行了许多重大改进。 最低要求的Java版本从Java 7增加到Java 8 现在&…

25寒假算法刷题 | Day1 | LeetCode 240. 搜索二维矩阵 II,148. 排序链表

目录 240. 搜索二维矩阵 II题目描述题解 148. 排序链表题目描述题解 240. 搜索二维矩阵 II 点此跳转题目链接 题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。每列的元素从上到…

何谓共赢?

A和B是人或组织,他们怎样的合作才是共赢呢? 形态1:A提供自己的身份证等个人信息,B用来作贷款等一些事务,A每月得到一笔钱。 A的风险远大于收益,或者B从事的是非法行为; 形态2:A单方面提前终止了与B的合作…

Kanass基础教程-创建项目

Kanass是一款国产开源免费的项目管理工具,工具简洁易用,开源免费,之前介绍过kanass的一些产品简介及安装配置方法,本文就从如何创建第一个项目来开始kanass上手之旅吧。 1. 创建项目 点击项目->项目添加 按钮进入项目添加页面…

实验9 JSP访问数据库(二)

实验9 JSP访问数据库(二) 目的: 1、熟悉JDBC的数据库访问模式。 2、掌握预处理语句的使用 实验要求: 1、使用Tomcat作为Web服务器 2、通过JDBC访问数据库,实现增删改查功能的实现 3、要求提交实验报告,将代…

单片机基础模块学习——DS1302时钟芯片

一、DS1302时钟简介 1.与定时器对比 DS1302时钟也称为RTC时钟(Real Time Clock,实时时钟),说到时钟,可能会想到定时器,下表来简单说明一下两者的区别。 定时器(Timer)实时时钟(RTC)精度高,可达微秒级精度较低,多为秒级计时范围短计时范围长2.开发板所在位置 下面方框里…

Vue+Echarts 实现青岛自定义样式地图

一、效果 二、代码 <template><div class"chart-box"><chart ref"chartQingdao" style"width: 100%; height: 100%;" :options"options" autoresize></chart></div> </template> <script> …

FIR滤波器:窗函数法

一、FIR滤波器基础 FIR&#xff08;有限脉冲响应&#xff09;滤波器的三大特点&#xff1a; 绝对稳定&#xff1a;没有反馈回路&#xff0c;不会出现失控振荡 线性相位&#xff1a;信号通过后波形不失真 直观设计&#xff1a;通过窗函数法、频率采样法等方法实现 二、窗函…

【AI】探索自然语言处理(NLP):从基础到前沿技术及代码实践

Hi &#xff01; 云边有个稻草人-CSDN博客 必须有为成功付出代价的决心&#xff0c;然后想办法付出这个代价。 目录 引言 1. 什么是自然语言处理&#xff08;NLP&#xff09;&#xff1f; 2. NLP的基础技术 2.1 词袋模型&#xff08;Bag-of-Words&#xff0c;BoW&#xff…

力扣动态规划-18【算法学习day.112】

前言 ###我做这类文章一个重要的目的还是记录自己的学习过程&#xff0c;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非常非常高滴&#xff01;&#xff01;&#xff01; 习题 1.下降路径最小和 题目链接:931. …

DBASE DBF数据库文件解析

基于Java实现DBase DBF文件的解析和显示 JDK19编译运行&#xff0c;实现了数据库字段和数据解析显示。 首先解析数据库文件头代码 byte bytes[] Files.readAllBytes(Paths.get(file));BinaryBufferArray bis new BinaryBufferArray(bytes);DBF dbf new DBF();dbf.VersionN…

【ESP32】ESP-IDF开发 | WiFi开发 | UDP用户数据报协议 + UDP客户端和服务器例程

1. 简介 UDP协议&#xff08;User Datagram Protocol&#xff09;&#xff0c;全称用户数据报协议&#xff0c;它是一种面向非连接的协议&#xff0c;面向非连接指的是在正式通信前不必与对方先建立连接&#xff0c; 不管对方状态就直接发送。至于对方是否可以接收到这些数据内…

tiktok 国际版抖抖♬♬ X-Bogus参数算法逆向分析

加密请求参数得到乱码&#xff0c;最终得到X-Bogus

C++ Primer 命名空间的using声明

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

c语言(关键字)

前言&#xff1a; 感谢b站鹏哥c语言 内容&#xff1a; 栈区&#xff08;存放局部变量&#xff09; 堆区 静态区&#xff08;存放静态变量&#xff09; rigister关键字 寄存器&#xff0c;cpu优先从寄存器里边读取数据 #include <stdio.h>//typedef&#xff0c;类型…

ARM内核:嵌入式时代的核心引擎

引言 在当今智能设备无处不在的时代&#xff0c;ARM&#xff08;Advanced RISC Machines&#xff09;处理器凭借其高性能、低功耗的特性&#xff0c;成为智能手机、物联网设备、汽车电子等领域的核心引擎。作为精简指令集&#xff08;RISC&#xff09;的典范&#xff0c;ARM核…

Airflow:选择合适执行器扩展任务执行

Apache Airflow是面向开发人员使用的&#xff0c;以编程方式编写、调度和监控的数据流程平台。可伸缩性是其关键特性之一&#xff0c;Airflow支持使用不同的执行器来执行任务。在本文中&#xff0c;我们将深入探讨如何利用这些执行器在Airflow中有效地扩展任务执行。 理解Airfl…