赞
踩
贪心算法(Greedy Algorithm)是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法策略。贪心算法在有最优子结构的问题中尤为有效,即局部最优解能决定全局最优解的问题。
贪心算法不保证会得到最优解,但在某些问题中,贪心算法的解足够接近最优解或者确实是最优解。贪心算法可以快速找到问题的可行解,因此对于要求不是很严格的问题,贪心算法可以作为一种简单而有效的解决方案。
简单直观:通常直接且易于实现。
贪心算法是一种通过在每一步选择当前可用的最佳选项来解决问题的方法。它不担心当前最佳结果是否会带来整体最优结果。
算法从不逆转早期的决定,即使选择是错误的。它采用自顶向下的方法。
我们可以通过以下属性来确定是否可以使用该算法解决问题:
20 + 3 + 1 = 24
。20 + 2 + 10 = 32
),如下面的图像所示。金额:$18
可用硬币为
$5硬币
$2硬币
$1硬币
您可以使用每种硬币的数量没有限制。
解决方案:
solution-set = { }
。可用硬币为{5, 2, 1}
。sum = 18
。让我们从sum = 0
开始。sum > 18
。(当我们在每一步选择最大值时,我们希望能够更快地到达目的地。这个概念被称为贪心选择属性。)solution-set = {5}
,sum = 5
。solution-set = {5, 5}
,sum = 10
。solution-set = {5, 5, 5}
,sum = 15
。solution-set = {5, 5, 5, 2}
,sum = 17
。(我们不能在这里选择5,因为如果我们这样做,sum = 20
,这比18大。所以,我们选择第二大的项目,即2。)sum = 18
,solution-set = {5, 5, 5, 2, 1}
。包括钱币找零问题、霍夫曼编码树的构建、以及图的最小生成树(使用普里姆算法)。
假设我们有不同面额的钱币,并且需要找零金额为amount
,我们希望使用尽可能少的钱币。
def coinChange(coins, amount): # 动态规划的解法,而非贪心算法 # 这里仅作为示例,因为贪心算法在这个问题中不总是有效 dp = [float('inf')] * (amount + 1) dp[0] = 0 for coin in coins: for i in range(coin, amount + 1): dp[i] = min(dp[i], dp[i - coin] + 1) return dp[amount] if dp[amount] != float('inf') else -1 # 示例 coins = [1, 2, 5] amount = 11 print(coinChange(coins, amount)) # 输出:3,因为可以选 5 + 5 + 1
霍夫曼编码是一种使用变长编码表对数据进行编码的方法,它是基于符号出现频率的贪心算法。
import heapq class Node: def __init__(self, char, freq): self.char = char self.freq = freq self.left = None self.right = None def __lt__(self, other): return self.freq < other.freq def calc_freq(data): freq = {} for char in data: if char not in freq: freq[char] = 0 freq[char] += 1 return freq def build_huffman_tree(data): freq = calc_freq(data) priority_queue = [Node(char, freq[char]) for char in freq] heapq.heapify(priority_queue) while len(priority_queue) > 1: left = heapq.heappop(priority_queue) right = heapq.heappop(priority_queue) merged = Node(None, left.freq + right.freq) merged.left = left merged.right = right heapq.heappush(priority_queue, merged) return priority_queue[0] # 示例 data = "this is an example for huffman encoding" tree = build_huffman_tree(data) print(tree)
普里姆算法是一种用于在加权图中找到最小生成树的贪心算法。
def prim(graph, start): visited = set() visited.add(start) edges = [] while len(visited) < len(graph): mim = float('inf') mim_edge = None for edge in graph: if edge[0] in visited and edge[1] not in visited: if edge[2] < mim: mim = edge[2] mim_edge = edge elif edge[1] in visited and edge[0] not in visited: if edge[2] < mim: mim = edge[2] mim_edge = edge if mim_edge is None: break visited.add(mim_edge[1]) edges.append(mim_edge) return edges # 示例 graph = [ ('A', 'B', 1), ('A', 'C', 3), ('B', 'C', 3), ('B', 'D', 1), ('C', 'D', 4), ('C', 'E', 2), ('D', 'E', 3) ] print(prim(graph, 'A'))
请注意,贪心算法并不总是能得到最优解,特别是在钱币找零问题中,贪心算法可能无法找到最少数量的钱币组合。在实际应用中,需要根据问题的具体性质和要求来选择是否使用贪心算法。
在实际应用中,是否使用贪心算法取决于问题的性质以及对解的质量要求。对于某些问题,贪心算法可以提供有效的近似解,而对于其他问题,则可能需要更复杂的算法来找到最优解。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。