数据结构与算法:贪心算法与应用场景

目录

11.1 贪心算法的原理

11.2 经典贪心问题

11.3 贪心算法在图中的应用

11.4 贪心算法的优化与扩展

总结


数据结构与算法:贪心算法与应用场景

贪心算法是一种通过选择当前最佳解来构造整体最优解的算法策略。贪心算法在很多实际问题中都取得了良好的效果,尤其在那些具有贪心选择性质和最优子结构的问题上。本章将深入探讨贪心算法的基本原理、经典问题及其应用,并使用表格对比贪心算法与其他算法的不同。

11.1 贪心算法的原理

贪心算法的核心思想是每一步都采取在当前情况下最优的选择,从而希望通过一系列最优的局部选择来达到整体最优。贪心算法适用于那些能够通过局部最优解构建全局最优解的问题。

贪心算法要素描述
贪心选择性质每一步的选择都可以保证局部最优,而不影响后续决策的整体最优性。
最优子结构整体问题的最优解由各个子问题的最优解组成。
与动态规划对比贪心算法只看局部最优,而动态规划则考虑所有可能的解。

贪心算法在一些问题中非常有效,但并不是所有问题都能通过贪心策略解决。问题是否适用贪心算法,需要仔细分析其贪心选择性质和最优子结构。

11.2 经典贪心问题

贪心算法在很多经典问题中都有应用,以下是几个典型的贪心问题。

问题名称问题描述贪心策略复杂度
活动选择问题从一组活动中选择尽可能多的互不重叠的活动。每次选择最早结束的活动。O(n log n)
哈夫曼编码构建最优二进制前缀码以压缩数据。每次合并最小权值的两个节点。O(n log n)
区间调度问题安排最大数量的兼容区间活动。每次选择最早结束的区间。O(n log n)
找零问题用最少的硬币数量找零(假设硬币面值适合贪心策略)。每次选择面值最大的硬币。O(n)

代码示例:活动选择问题的实现

#include <stdio.h>
#include <stdlib.h>struct Activity {int start;int end;
};int compare(const void* a, const void* b) {return ((struct Activity*)a)->end - ((struct Activity*)b)->end;
}void activitySelection(struct Activity activities[], int n) {qsort(activities, n, sizeof(struct Activity), compare);printf("选择的活动: \n");int i = 0;printf("(%d, %d)\n", activities[i].start, activities[i].end);for (int j = 1; j < n; j++) {if (activities[j].start >= activities[i].end) {printf("(%d, %d)\n", activities[j].start, activities[j].end);i = j;}}
}int main() {struct Activity activities[] = {{1, 3}, {2, 5}, {4, 7}, {1, 8}, {5, 9}, {8, 10}};int n = sizeof(activities) / sizeof(activities[0]);activitySelection(activities, n);return 0;
}

在上述代码中,通过贪心策略选择最早结束的活动,可以得到一组互不重叠的活动,从而最大化所选活动的数量。

11.3 贪心算法在图中的应用

贪心算法在图论中也有广泛应用,尤其是在最小生成树和最短路径问题中。

算法名称问题描述贪心策略复杂度
Prim算法构建最小生成树,使得总权重最小。每次选择权值最小且能扩展树的边。O(V^2) 或 O(E log V)
Kruskal算法构建最小生成树,使得总权重最小。每次选择权值最小且不形成环的边。O(E log E)
Dijkstra算法从单源点出发,找到到其他各点的最短路径。每次选择当前距离最小的未处理顶点。O(V^2) 或 O(E log V)

代码示例:Prim算法的实现

#include <stdio.h>
#include <limits.h>
#include <stdbool.h>
#define V 5int minKey(int key[], bool mstSet[]) {int min = INT_MAX, minIndex;for (int v = 0; v < V; v++) {if (mstSet[v] == false && key[v] < min) {min = key[v], minIndex = v;}}return minIndex;
}void printMST(int parent[], int graph[V][V]) {printf("边  权重\n");for (int i = 1; i < V; i++) {printf("%d - %d    %d\n", parent[i], i, graph[i][parent[i]]);}
}void primMST(int graph[V][V]) {int parent[V];int key[V];bool mstSet[V];for (int i = 0; i < V; i++) {key[i] = INT_MAX, mstSet[i] = false;}key[0] = 0;parent[0] = -1;for (int count = 0; count < V - 1; count++) {int u = minKey(key, mstSet);mstSet[u] = true;for (int v = 0; v < V; v++) {if (graph[u][v] && mstSet[v] == false && graph[u][v] < key[v]) {parent[v] = u, key[v] = graph[u][v];}}}printMST(parent, graph);
}int main() {int graph[V][V] = {{0, 2, 0, 6, 0},{2, 0, 3, 8, 5},{0, 3, 0, 0, 7},{6, 8, 0, 0, 9},{0, 5, 7, 9, 0}};primMST(graph);return 0;
}

在这个代码中,通过 Prim 算法找到最小生成树,每次选择未被包含在树中的、具有最小权重的边来扩展生成树。

11.4 贪心算法的优化与扩展

虽然贪心算法在某些问题上能够很好地工作,但它的局限性在于无法保证所有情况下的全局最优解。因此,针对特定问题,可以通过以下方法对贪心算法进行优化或扩展:

优化策略描述
启发式优化在贪心选择的基础上加入启发式信息,提高对全局解的估计精度。
与动态规划结合将贪心算法与动态规划结合,使用动态规划来处理贪心策略的不足。
混合算法将贪心算法与其他算法结合,如回溯或分支限界,以求得最优解。

贪心算法在很多情况下非常高效,但对于无法满足贪心性质的问题,需要考虑其他的算法策略。通过将贪心与动态规划等方法结合,通常可以找到更优的解。

总结

本章深入介绍了贪心算法的基本原理及其在各种经典问题中的应用。通过表格比较和代码示例,我们了解了贪心算法在活动选择、最小生成树、最短路径等场景中的广泛应用。同时,我们讨论了贪心算法的局限性及其与其他算法的结合方式。在下一章中,我们将深入探讨动态规划的核心思想及其在复杂问题中的应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/57485.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NGINX 保护 Web 应用安全之基于 IP 地址的访问

根据客户端的 IP 地址控制访问 使用 HTTP 或 stream 访问模块控制对受保护资源的访问&#xff1a; location /admin/ { deny 10.0.0.1; allow 10.0.0.0/20; allow 2001:0db8::/32; deny all; } } 给定的 location 代码块允许来自 10.0.0.0/20 中的任何 IPv4 地址访问&#xf…

如何保证测试用例的充分性?

需求理解与分析&#xff1a; 深入理解软件需求规格说明书&#xff08;SRS&#xff09;&#xff0c;确保所有需求都被正确理解。 将需求分解为更小的、可测试的功能点或特性。 等价类划分&#xff1a; 将输入数据划分为若干等价类&#xff0c;从每个等价类中选取一个或少数几个…

【AIGC】优化长提示词Prompt:提升ChatGPT输出内容的准确性与实用性

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;长提示词的挑战&#x1f4af;谷歌的优化长提示词技术关键因素分析 &#x1f4af;长提示词的设计原则&#x1f4af;优化长提示词的新框架方法&#x1f4af;实验结果分析不…

“网络协议入门:HTTP通信的四大组成部分“

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f439;今日诗词: 春水满四泽&#xff0c;夏云多奇峰&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微…

Android 13 SystemUI 隐藏下拉快捷面板部分模块(wifi,bt,nfc等)入口

frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java createTileInternal(tileSpec)方法注释想隐藏的模块即可。

GitHub加速

GitHub加速 终端命令行 支持终端命令行 git clone , wget , curl 等工具下载. 支持 raw.githubusercontent.com , gist.github.com , gist.githubusercontent.com 文件下载.注意&#xff1a;不支持 SSH Key 方式 git clone 下载. git clone git clone https://ghp.ci/https:…

【leetcode|哈希表、动态规划】最长连续序列、最大子数组和

目录 最长连续序列 解法一&#xff1a;暴力枚举 复杂度 解法二&#xff1a;优化解法一省去二层循环中不必要的遍历 复杂度 最大子数组和 解法一&#xff1a;暴力枚举 复杂度 解法二&#xff1a;贪心 复杂度 解法三&#xff1a;动态规划 复杂度 最长连续序列 输入输…

Mac 远程 Windows 等桌面操作系统工具 Microsoft Remote Desktop for Mac 下载安装详细使用教程

最近需要在 Mac 上远程连接控制我的 windows 电脑系统&#xff0c;经过一番尝试对于 win 来说还是微软自家推出的 Microsoft Remote Desktop for Mac 最最好用&#xff0c;没有之一 简介 Microsoft Remote Desktop是一款由微软公司开发的远程桌面连接工具&#xff0c;可以让用…

Linux基础——信号

目录 1. 什么是信号&#xff1f; 2. 信号的产生 ①键盘的组合键 ②kill命令 ④产生异常 ⑤软件条件 ⑥进程等待中的core dump 3. 信号的保存 ①信号的发送与接收 ②为什么需要保存信号&#xff1f; ③信号是如何保存的 4. 信号的捕捉处理 ①信号的处理与处理时机…

Redis Time Series介绍和命令大全

Redis Time Series介绍和命令大全 Redis Time Series1 时序序列是什么2 Redis Time Series的特性3 內存模型4 命令详解命名链接表命名详解表TS.CREATETS.ADDTS.ALTERTS.CREATERULETS.DECRBYTS.DELTS.DELETERULETS.GETTS.INCRBYTS.INFOTS.MADDTS.MGETTS.MRANGETS.MREVRANGETS.QU…

WORFBENCH:一个创新的评估基准,目的是全面测试大型语言模型在生成复杂工作流 方面的性能。

2024-10-10,由浙江大学和阿里巴巴集团联合创建的WORFBENCH&#xff0c;一个用于评估大型语言模型&#xff08;LLMs&#xff09;生成工作流能力的基准测试。它包含了一系列的测试和评估协议&#xff0c;用于量化和分析LLMs在处理复杂任务时分解问题和规划执行步骤的能力。WORFBE…

Python 第七节 魔法圆阵

这里写目录标题 1. 回顾:2. 绘图小游戏 - 深入探索turtle模块2.1 turtle.pensize():设置画笔的宽度。2.2 turtle.speed():设置画笔的速度2.3 t.hideturtle():2.4 t.showturtle():3. 变换精灵(变量)& 永恒精灵(常量)3.1 变换精灵:3.2 永恒精灵:3.3 标识符:4.数字…

postgresql是国产数据库吗?

PostgreSQL不是国产数据库。但是PostgreSQL对国产数据库的发展有着重要影响&#xff0c;许多国产数据库产品是基于PostgreSQL进行二次开发的。 PostgreSQL的开源特性也是其受欢迎的重要原因之一。开源意味着任何人都可以查看、修改和使用PostgreSQL的源代码。这使得PostgreSQL…

windows安装superset及各种问题解决

1,背景 先说说背景,之前在2月份已经安装过superset3.1.1,当时还没有提示SECRET_KEY异常,能正常运行,且已配置数据库连接. 2,报错信息及解决途径 1,创建admin时,提示Error! User already exists 这个是因为之前已经创建过admin用户,需要删除C:\Users\用户名\.superset下的.…

微信小程序文本收起展开

这里写自定义目录标题 微信小程序文本收起展开常见问题的梯形背景框 微信小程序文本收起展开 参考 https://juejin.cn/post/6963904955262435336 <!-- 常见问题解答 --><view classcontentBottom><view classBottomFirst><text id0 data-id0 class&quo…

python从0快速上手(十六)小游戏开发

Python小游戏开发&#xff1a;创造你的第一款游戏 你是否曾梦想过成为一名游戏开发者&#xff0c;创造出属于自己的游戏世界&#xff1f;随着技术的发展&#xff0c;这个梦想不再遥不可及。Python&#xff0c;作为一种易于学习和使用的编程语言&#xff0c;搭配其强大的库支持…

六万字77道Spring面试题总结(2024版)

文章目录 问题1&#xff1a;什么是Spring?问题2&#xff1a;Spring的两大核心概念是什么&#xff1f;问题3&#xff1a;Spring框架的设计目标、设计理念和核心是什么&#xff1f;问题4&#xff1a;Spring的优缺点是什么&#xff1f;问题5&#xff1a;Spring有哪些应用场景&…

MySQL事务及实现原理

一、MySQL事务简单介绍 MySQL事务是指一组操作&#xff0c;它们被看作一个单独的工作单元&#xff0c;要么全部成功&#xff0c;要么全部失败回滚。在MySQL中&#xff0c;事务可以确保数据的一致性和完整性。 事务通常由四个关键词来描述&#xff1a; 1、BEGIN 或 START TRAN…

Java-关于Java是值传递还是引用传递的解读(附代码实例解读)

大家都知道Java是面向对象编程&#xff0c;那么有没有考虑过在传递的过程中&#xff0c;究竟传递的是值&#xff0c;还是值的引用呢&#xff1f;下面我们先来看一下什么事值传递和引用传递。 值传递&#xff1a;指在调用函数时将实际参数复制一份传递到函数中&#xff0c;这样如…

安装buildkit,并使用buildkit构建containerd镜像

背景 因为K8s抛弃Docker了,所以就只装了个containerd,这样就需要一个单独的镜像构建工具了,就用了buildkit,这也是Docker公司扶持的,他们公司的人出来搞的开源工具,官网在 https://github.com/moby/buildkit 简介 服务端为buildkitd,负责和runc或containerd后端连接干活,目前…