python 实现贪心算法(Greedy Algorithm)

news/2025/1/7 5:34:55/

贪心算法(Greedy Algorithm)是一种在每一步选择中都采取当前最优的选择,希望通过局部最优解达到全局最优解的算法设计方法。以下是使用Python实现贪心算法解决几个经典问题的示例:


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

活动选择问题是选择最多的互不冲突的活动。

python">def activity_selection(activities):# 按结束时间排序activities.sort(key=lambda x: x[1])selected = []last_end = -1for start, end in activities:if start >= last_end:selected.append((start, end))last_end = endreturn selected# 示例
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))
# 输出: [(1, 4), (5, 7), (8, 11), (12, 16)]

2. 霍夫曼编码(Huffman Coding)

霍夫曼编码是一种用于数据压缩的贪心算法

python">import heapqclass HuffmanNode:def __init__(self, char, freq):self.char = charself.freq = freqself.left = Noneself.right = Nonedef __lt__(self, other):return self.freq < other.freqdef build_huffman_tree(freq_map):heap = [HuffmanNode(char, freq) for char, freq in freq_map.items()]heapq.heapify(heap)while len(heap) > 1:left = heapq.heappop(heap)right = heapq.heappop(heap)merged = HuffmanNode(None, left.freq + right.freq)merged.left = leftmerged.right = rightheapq.heappush(heap, merged)return heapq.heappop(heap)def build_huffman_codes(node, prefix="", code_map=None):if code_map is None:code_map = {}if node:if node.char:code_map[node.char] = prefixbuild_huffman_codes(node.left, prefix + "0", code_map)build_huffman_codes(node.right, prefix + "1", code_map)return code_map# 示例
freq_map = {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}
huffman_tree = build_huffman_tree(freq_map)
huffman_codes = build_huffman_codes(huffman_tree)
print(huffman_codes)
# 输出: {'f': '0', 'c': '100', 'd': '101', 'a': '1100', 'b': '1101', 'e': '111'}

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

最小生成树问题可以通过 Kruskal 或 Prim 算法解决。以下是 Kruskal 算法的实现。

python">class Graph:def __init__(self, vertices):self.V = verticesself.edges = []def add_edge(self, u, v, w):self.edges.append((u, v, w))def find(self, parent, i):if parent[i] == i:return ireturn self.find(parent, parent[i])def union(self, parent, rank, x, y):xroot = self.find(parent, x)yroot = self.find(parent, y)if rank[xroot] < rank[yroot]:parent[xroot] = yrootelif rank[xroot] > rank[yroot]:parent[yroot] = xrootelse:parent[yroot] = xrootrank[xroot] += 1def kruskal_mst(self):result = []self.edges.sort(key=lambda x: x[2])  # 按权重排序parent = [i for i in range(self.V)]rank = [0] * self.Vfor u, v, w in self.edges:x = self.find(parent, u)y = self.find(parent, v)if x != y:result.append((u, v, w))self.union(parent, rank, x, y)return result# 示例
g = Graph(4)
g.add_edge(0, 1, 10)
g.add_edge(0, 2, 6)
g.add_edge(0, 3, 5)
g.add_edge(1, 3, 15)
g.add_edge(2, 3, 4)
print(g.kruskal_mst())
# 输出: [(2, 3, 4), (0, 3, 5), (0, 1, 10)]

4. 硬币找零问题(Coin Change Problem)

硬币找零问题是使用最少数量的硬币凑成指定金额。

python">def coin_change(coins, amount):coins.sort(reverse=True)  # 从大到小排序result = []for coin in coins:while amount >= coin:result.append(coin)amount -= coinreturn result if amount == 0 else None# 示例
coins = [1, 2, 5, 10, 20, 50, 100, 500, 1000]
amount = 93
print(coin_change(coins, amount))
# 输出: [50, 20, 20, 2, 1]

总结

贪心算法的核心思想是每一步都选择当前最优的解,希望通过局部最优解达到全局最优解。然而,贪心算法并不总是能得到全局最优解,因此在使用时需要验证问题的性质是否适合贪心策略。


http://www.ppmy.cn/news/1560923.html

相关文章

太速科技-754-基于Agilex™ 7 FPGA F 系列的PCIe4.0X16 加速卡

基于Agilex™ 7 FPGA F 系列的PCIe4.0X16 加速卡 一、板卡概述 Agilex™ 7 FPGA 开发套件提供了一个硬件开发平台&#xff0c;用于评估具有两个 F-Tile 的 Agilex™ 7 FPGA F 系列的性能和特性。这是一款 PCIe 外形的通用评估板&#xff0c;具有 HPS 硬件功能。 使用 Agilex™…

VSCode 插件开发实战(十六):详解插件生命周期

前言 VSCode 它不仅功能强大&#xff0c;而且可以通过插件进行扩展&#xff0c;以满足不同开发者的需求。那么&#xff0c;VSCode 自定义插件的生命周期是如何运行的呢&#xff1f;今天我们就用通俗易懂的方式来讲解一下。 什么是 VSCode 插件&#xff1f; VSCode 插件是用来…

WinForm开发-自定义组件-1. 工具栏: UcompToolStrip

这里写自定义目录标题 1. 工具栏: UcompToolStrip1.1 展示效果1.2 代码UcompToolStrip.csUcompToolStrip.Designer.cs 1. 工具栏: UcompToolStrip 自定义一些Winform组件 1.1 展示效果 1&#xff09;使用效果 2&#xff09;控件事件 1.2 代码 设计 编码 UcompToolStrip.…

c++ vector 使用find查找指定元素方法

在 C 中&#xff0c;std::vector 是一个动态数组&#xff0c;用于存储同类型元素的序列。如果你想在 std::vector 中查找指定元素&#xff0c;可以使用 std::find 算法。std::find 是定义在 <algorithm> 头文件中的标准库函数。 以下是一个示例代码&#xff0c;展示了如…

Elasticsearch Serverless中的数据流自动分片深度解析

Elasticsearch Serverless中的数据流自动分片深度解析 一、Elasticsearch Serverless概述 1. 什么是Elasticsearch Serverless Elasticsearch Serverless是一种云端全托管的Elasticsearch服务&#xff0c;它基于云原生Serverless技术架构&#xff0c;提供自动弹性和完全免运…

PyTorch快速入门教程【小土堆】之全连接层

视频地址神经网络-线性层及其他层介绍_哔哩哔哩_bilibili 视频中称为线性层 import torch import torchvision from torch import nn from torch.nn import Linear from torch.utils.data import DataLoaderdataset torchvision.datasets.CIFAR10("CIFAR10", trai…

C#进程和线程详解

C#进程和线程详解 进程&#xff1a; 进程是系统进行资源分配的基本单位&#xff0c;是操作系统结构的基础。在早期面向进程设计的计算机结构中&#xff0c;进程是程序的基本执行实体&#xff1b;在当代面向线程设计的计算机结构中&#xff0c;进程是线程的容器。进程记录了当…

Nginx与frp结合实现局域网和公网的双重https服务

背景&#xff1a; 因为局域网内架设了 tiddlywiki、 Nextcloud 等服务&#xff0c;同时也把公司的网站架设在了本地&#xff0c;为了实现局域网直接在局域网内访问&#xff0c;而外部访问通过frps服务器作为反向代理的目的&#xff0c;才有此内容。 实现的效果如下图琐事 不喜欢…