算法学习6——贪心算法

什么是贪心算法?

贪心算法是一种在每一步选择中都采取当前状态下最优或最有利的选择的算法。其核心思想是通过一系列局部最优选择来达到全局最优解。贪心算法广泛应用于各种优化问题,如最短路径、最小生成树、背包问题等。

贪心算法的特点

  1. 局部最优选择:每一步都做出在当前情况下最优的选择。
  2. 无后效性:一旦某个状态被确定,就不会再被改变或回溯。
  3. 逐步构造解决方案:通过一系列的选择逐步构建出最终的解决方案。

经典例子及其Python实现

1. 活动选择问题

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

贪心策略:每次选择结束时间最早且不与已选择活动重叠的活动。

实现过程:

  1. 将所有活动按结束时间排序。
  2. 依次选择结束时间最早且不与已选择活动重叠的活动。

Python代码:

python 复制代码
def activity_selection(activities):
    # 按结束时间排序
    activities.sort(key=lambda x: x[1])
    
    # 选择活动
    selected_activities = [activities[0]]
    last_end_time = activities[0][1]
    
    for start, end in activities[1:]:
        if start >= last_end_time:
            selected_activities.append((start, end))
            last_end_time = end
    
    return selected_activities

# 示例
activities = [(1, 4), (3, 5), (0, 6), (5, 7), (3, 9), (5, 9), (6, 10), (8, 11), (8, 12), (2, 14), (12, 16)]
print(activity_selection(activities))

2. 背包问题

问题描述:给定一组物品,每个物品有重量和价值,要求在总重量不超过背包容量的前提下,使背包中的物品总价值最大。

贪心策略:每次选择单位重量价值最高的物品。

实现过程:

  1. 将所有物品按单位重量价值排序。
  2. 依次选择单位重量价值最高且不超过剩余容量的物品。

Python代码:

python 复制代码
def knapsack(items, capacity):
    # 按单位重量价值排序
    items.sort(key=lambda x: x[1]/x[0], reverse=True)
    
    total_value = 0
    for weight, value in items:
        if capacity >= weight:
            capacity -= weight
            total_value += value
        else:
            total_value += value * (capacity / weight)
            break
    
    return total_value

# 示例
items = [(10, 60), (20, 100), (30, 120)]
capacity = 50
print(knapsack(items, capacity))

3. 哈夫曼编码

问题描述:给定一组字符及其出现频率,要求构造一个前缀码,使得编码后的字符串长度最短。

贪心策略:每次选择出现频率最低的两个字符合并,构造哈夫曼树。

实现过程:

  1. 将所有字符按频率构造最小堆。
  2. 依次取出频率最低的两个节点,合并后重新插入堆中。
  3. 重复上述过程,直到所有节点合并为一棵树。

Python代码:

python 复制代码
import heapq

def huffman_encoding(frequencies):
    heap = [[weight, [symbol, ""]] for symbol, weight in frequencies.items()]
    heapq.heapify(heap)
    
    while len(heap) > 1:
        lo = heapq.heappop(heap)
        hi = heapq.heappop(heap)
        for pair in lo[1:]:
            pair[1] = '0' + pair[1]
        for pair in hi[1:]:
            pair[1] = '1' + pair[1]
        heapq.heappush(heap, [lo[0] + hi[0]] + lo[1:] + hi[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}
print(huffman_encoding(frequencies))

结论

贪心算法通过局部最优选择来构建全局最优解,简单高效,适用于多种优化问题。然而,贪心算法并不总是能得到最优解,因此在使用前需要确保问题满足贪心选择性质。

相关推荐
星恒随风3 分钟前
Linux进程信号(一):从Ctrl+C到kill、raise、alarm,深入理解信号的概念与产生原理
linux·c语言·笔记·学习·状态模式
碧海银沙音频科技研究院8 分钟前
基于炬芯ATS3089X音箱的音乐播放歌词显示功能实现
人工智能·驱动开发·嵌入式硬件·算法
2603_9695792813 分钟前
怎样取消电脑上的自动备份?不同来源的关闭方法
学习
CV@CV19 分钟前
世界模型环境预测与内在表征基础原理
人工智能·学习·边缘计算·量子计算·具身智能
知识分享小能手21 分钟前
C学习教程,从入门到精通,C语言数组 —— 知识点详解(8)
c语言·学习·算法
hetao173383724 分钟前
联盟场-提高组-R2 & ZYZSC-S-Round 5
c++·算法
卿卿的产品经理日记26 分钟前
【AI产品经理实战】Day 34|计算机科学速成②:从水流开关到 Unicode,把整个电脑拆成一长串 0 和 1
人工智能·笔记·科技·学习·产品经理
其实防守也摸鱼35 分钟前
Codex 下载与本地部署实战指南
linux·服务器·前端·数据库·算法·ai
南极企鹅36 分钟前
生产环境gc文件分析
java·jvm·算法
希洛兔38 分钟前
原码、反码、补码:一张图讲透计算机里的负数表示
算法·面试