贪心算法是一种在每一步选择中都采取当前最优解的算法,期望通过局部最优解达到全局最优解。下面是几个经典的贪心算法问题以及其 Python 实现。
1. 活动选择问题 (Activity Selection Problem)
活动选择问题是给定多个活动的开始和结束时间,选择尽可能多的活动,使得这些活动互不冲突。
def activity_selection(start_times, end_times):
activities = sorted(zip(start_times, end_times), key=lambda x: x[1])
selected_activities = []
last_end_time = 0
for start, end in activities:
if start >= last_end_time:
selected_activities.append((start, end))
last_end_time = end
return selected_activities
# Example usage
start_times = [1, 3, 0, 5, 8, 5]
end_times = [2, 4, 6, 7, 9, 9]
print(activity_selection(start_times, end_times))
2. 分数背包问题 (Fractional Knapsack Problem)
分数背包问题是给定一组物品,每个物品有一定的重量和价值,背包有固定的容量,要求在不超过背包容量的前提下,最大化背包内物品的总价值。不同于 0-1 背包问题,这里可以选择部分物品。
def fractional_knapsack(weights, values, capacity):
index = list(range(len(values)))
ratio = [v / w for v, w in zip(values, weights)]
index.sort(key=lambda i: ratio[i], reverse=True)
max_value = 0
for i in index:
if weights[i] <= capacity:
max_value += values[i]
capacity -= weights[i]
else:
max_value += values[i] * (capacity / weights[i])
break
return max_value
# Example usage
weights = [10, 20, 30]
values = [60, 100, 120]
capacity = 50
print(fractional_knapsack(weights, values, capacity))
3. 霍夫曼编码 (Huffman Coding)
霍夫曼编码是一种用于数据压缩的贪心算法,通过构建一棵前缀树(霍夫曼树)来实现数据的无损压缩。
import heapq
class Node:
def __init__(self, freq, symbol, left=None, right=None):
self.freq = freq
self.symbol = symbol
self.left = left
self.right = right
self.huff = ''
def __lt__(self, other):
return self.freq < other.freq
def 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)
left.huff = '0'
right.huff = '1'
new_node = Node(left.freq + right.freq, left.symbol + right.symbol, left, right)
heapq.heappush(heap, new_node)
def get_codes(node, val=''):
new_val = val + node.huff
if node.left is None and node.right is None:
return {node.symbol: new_val}
codes = {}
if node.left:
codes.update(get_codes(node.left, new_val))
if node.right:
codes.update(get_codes(node.right, new_val))
return codes
root = heap[0]
return get_codes(root)
# Example usage
symbols = ['A', 'B', 'C', 'D', 'E', 'F']
frequencies = [5, 9, 12, 13, 16, 45]
codes = huffman_coding(symbols, frequencies)
print(codes)
这些例子展示了如何在不同问题中应用贪心算法。每个问题都通过局部最优选择,期望达到全局最优解。