探索贪心算法:解决优化问题的高效策略

贪心算法是一种在每一步选择中都采取当前最佳选择的算法,以期在整体上达到最优解。它广泛应用于各种优化问题,如最短路径、最小生成树、活动选择等。本文将介绍贪心算法的基本概念、特点、应用场景及其局限性。

贪心算法的基本概念

贪心算法的核心思想是局部最优策略,即在每一步选择中都选择当前看起来最优的选项,希望通过一系列的局部最优选择达到全局最优。

贪心算法的特点

  1. 局部最优选择:每一步都选择当前状态下最优的操作。

  2. 无需回溯:一旦做出选择,便不会更改。

  3. 逐步构建解决方案:从一个初始解开始,通过局部最优选择逐步构建完整解决方案。

贪心算法的应用场景

1. 活动选择问题

在活动选择问题中,给定一组活动及其开始和结束时间,要求选择尽可能多的互不重叠的活动。

复制代码
def activity_selection(activities):
    activities.sort(key=lambda x: x[1])  # 按结束时间排序
    selected_activities = [activities[0]]
    
    for i in range(1, len(activities)):
        if activities[i][0] >= selected_activities[-1][1]:
            selected_activities.append(activities[i])
    
    return selected_activities

activities = [(0, 6), (1, 4), (3, 5), (5, 7), (3, 9), (5, 9), (6, 10), (8, 11), (8, 12), (2, 14), (12, 16)]
selected = activity_selection(activities)
print("Selected activities:", selected)

2. 背包问题(分数背包)

在分数背包问题中,物品可以部分装入背包。目标是选择物品使得背包中的总价值最大。

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

items = [(10, 60), (20, 100), (30, 120)]  # (weight, value)
capacity = 50
max_value = fractional_knapsack(items, capacity)
print("Maximum value in knapsack:", max_value)

3. 最小生成树(Kruskal 算法)

在图论中,最小生成树是连接所有顶点的权重最小的树。Kruskal 算法通过贪心策略选择最小边来构建最小生成树。

复制代码
class DisjointSet:
    def __init__(self, n):
        self.parent = list(range(n))
        self.rank = [0] * n

    def find(self, u):
        if self.parent[u] != u:
            self.parent[u] = self.find(self.parent[u])
        return self.parent[u]

    def union(self, u, v):
        root_u = self.find(u)
        root_v = self.find(v)
        if root_u != root_v:
            if self.rank[root_u] > self.rank[root_v]:
                self.parent[root_v] = root_u
            elif self.rank[root_u] < self.rank[root_v]:
                self.parent[root_u] = root_v
            else:
                self.parent[root_v] = root_u
                self.rank[root_u] += 1

def kruskal(n, edges):
    ds = DisjointSet(n)
    edges.sort(key=lambda x: x[2])
    mst = []
    for u, v, weight in edges:
        if ds.find(u) != ds.find(v):
            ds.union(u, v)
            mst.append((u, v, weight))
    return mst

edges = [(0, 1, 10), (0, 2, 6), (0, 3, 5), (1, 3, 15), (2, 3, 4)]
n = 4  # Number of vertices
mst = kruskal(n, edges)
print("Edges in MST:", mst)

贪心算法的局限性

虽然贪心算法在许多问题中表现出色,但它并不适用于所有问题。贪心算法不能保证所有情况下都能找到全局最优解。例如,在0-1背包问题中,贪心算法可能无法找到最优解。

文章转载自: 最小生成树

原文链接: https://www.cnblogs.com/zx618/p/18300342

体验地址: 引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

相关推荐
CM莫问2 小时前
<论文>(微软)避免推荐域外物品:基于LLM的受限生成式推荐
人工智能·算法·大模型·推荐算法·受限生成
康谋自动驾驶3 小时前
康谋分享 | 自动驾驶仿真进入“标准时代”:aiSim全面对接ASAM OpenX
人工智能·科技·算法·机器学习·自动驾驶·汽车
C++ 老炮儿的技术栈4 小时前
什么是函数重载?为什么 C 不支持函数重载,而 C++能支持函数重载?
c语言·开发语言·c++·qt·算法
yychen_java4 小时前
R-tree详解
java·算法·r-tree
MarkHard1235 小时前
Leetcode (力扣)做题记录 hot100(62,64,287,108)
算法·leetcode·职场和发展
一只鱼^_6 小时前
牛客练习赛138(首篇万字题解???)
数据结构·c++·算法·贪心算法·动态规划·广度优先·图搜索算法
一只码代码的章鱼6 小时前
Spring的 @Validate注解详细分析
前端·spring boot·算法
邹诗钰-电子信息工程6 小时前
嵌入式自学第二十一天(5.14)
java·开发语言·算法
↣life♚6 小时前
从SAM看交互式分割与可提示分割的区别与联系:Interactive Segmentation & Promptable Segmentation
人工智能·深度学习·算法·sam·分割·交互式分割
zqh176736464697 小时前
2025年阿里云ACP人工智能高级工程师认证模拟试题(附答案解析)
人工智能·算法·阿里云·人工智能工程师·阿里云acp·阿里云认证·acp人工智能