当前位置: 首页 > news >正文

一文带你理解算法策略

cccc164dd74e159006bb023e6328f955.gif

一个精心设计的算法尽可能地将问题划分为更小的子问题,从而最大限度地优化可用资源的使用。设计算法有不同的算法策略,算法策略包含下面列出的三种典型策略,还有些策略没有列入进来。

这里,我们介绍以下三种策略:

  • 分治策略

  • 动态规划策略

  • 贪心算法策略

01

分治策略

分治策略就是找到一种方法,将规模较大的问题分解成可以相互独立解决的规模较小的子问题,然后将这些子问题产生的解合并起来,生成问题整体的解,这就是所谓的分治策略

从数学上讲,如果问题(P)有n个输入且需要对数据集d进行处理,则用分治策略为问题设计求解方案会将问题分解成k个子问题,记为P1至Pk,每个子问题将处理数据集d的一个分区。通常,假设P1至Pk依次处理数据分区d1至dk

我们看一个实例。

实例—适用于Apache Spark的分治策略

Apache Spark是一个用于解决复杂分布式问题的开源框架,它使用了分治策略来解决问题。为了处理问题,它将问题分为多个子问题,并且彼此独立地处理。我们将通过从一个列表中计数单词的简单的例子来说明这一点。

假设我们有以下单词列表:

8af0b3bb8306da43e72582785a04fcd4.png

我们要计算此列表中每个单词出现的频率。为此,我们将采用分治策略来有效解决此问题。

图4-3展示了分治策略的实现流程。

bf1ca373597534d312773cd660ed891e.png

在图4-3中,我们将一个问题划分为以下几个阶段:

  • 分割(splitting):在这个阶段中,输入数据被分为可以相互独立处理的分区,这称为分割。图4-3中我们有三个分区。 

  • 变换(Mapping):可以在分区上独立运行的任何操作都称为变换。在图4-3中,变换操作将分区中的每个单词转换为键值对,对应于三个分区,有三个并行运行的变换器。

  • 混合(shuffling):混合是将相似的键组合在一起的过程。一旦相似的键聚集在一起,聚合函数就可以在它们的值上运行。请注意,混合是性能密集型的操作,因为需要将原本分布在网络各处的相似键聚集在一起。

  • 聚合(reducing):在相似键的值上运行一个聚合函数的操作叫作聚合。在图4-3中,我们要计算每个单词的个数。

我们看看如何通过编写代码来实现此目的。为了演示分治策略,我们需要使用一个分布式的计算框架。为此,我们将在Apache Spark上运行Python:

1. 首先,为了使用Apache Spark,我们创建一个Apache Spark的运行环境:

b4fe903ca742d9afe562d1d83e887b8a.png

2. 现在,我们创建一个包含一些单词的示例列表。我们将把这个列表转换成Spark的本地分布式数据结构,称为弹性分布式数据集(Resilient Distributed Dataset,RDD)

97116cf86e4085a69a913913925ac7c2.png

3. 现在,我们使用map函数将单词转换为键值对(如图4-4所示)。

e56d32a801f2cf827a1dffc5f4d89c18.png

4. 我们使用reduce函数进行聚合,并获得最终结果(如图4-5所示)。

44d897a29d1be7dbfe9b448bc28932d4.png

这演示了我们是如何使用分治策略来计算单词出现次数的。

诸如Microsoft Azure、Amazon Web Services和Google Cloud之类的现代云计算基础设施通过直接或间接在幕后实施分治策略来实现可扩展性。

4389772b18996e5f42effe778e3b164c.gif

02

动态规划策略

动态规划是由理查德·贝尔曼(Richard Bellman)在20世纪50年代提出的一种用于优化某类算法的策略。它基于智能缓存机制,尝试重用大量计算,这种智能缓存机制称为记忆

当我们要解决的问题可以拆分为若干子问题时,动态规划可带来良好的性能优势。子问题部分涉及了一些会在不同的子问题中重复的计算,我们的想法是执行一次计算(这是耗时的步骤),然后在其他子问题上重复使用计算结果。这在解决递归问题时尤其有用,因为这些问题可能会多次计算相同的输入。

03

贪心算法

在深入展开讨论之前,我们先定义两个术语:

  • 算法开销:在我们尝试找出确定型问题的最优解时,都要花费一些时间。随着我们要求解的优化问题变得越来越复杂,找出最优解所花费的时间也会增加。我们用Ωi表示算法开销。

  • 最优解增量:给定的优化问题都存在一个最优解。在通常情况下,我们用自己选择的算法对解迭代地进行优化。对于给定的问题,总是存在当前问题的一个完美解,称为最优解。如前所述,根据待求解问题的类型,最优解有可能是未知的,或者说计算和验证最优解需要花费的时间长到人们无法接受。假设最优解是已知的,那么在第i轮迭代中,当前解与最优解的差称为最优解增量,用7a503aa7274bf39b483131b7552df2a9.png 表示。

对于复杂问题,我们有两种可行的策略:

  • 策略1:花更多时间寻找最接近最优解的解,使得bde82d2daa448ec54146400004fbbe72.png尽可能小。

  • 策略2:最小化算法开销Ωi,采用快刀斩乱麻的方法,只需使用可行解即可。

贪心算法基于策略2,它并不致力于找出全局最优解,而是选择最小化算法开销。

采用贪心算法是为多阶段问题找出全局最优解的一种快速简单的策略。它基于选择局部最优值而无须费力去验证局部最优值是否也是全局最优的。一般来说,除非我们很幸运,否则贪心算法找到的解不会被当作全局最优解,因为寻找全局最优解通常是一项非常耗时的任务。因此,与分治算法和动态规划算法相比,贪心算法的速度很快。

通常,贪心算法定义如下:

1. 假设我们有一个数据集D。在这个数据集中,选择一个元素k。

2. 假设当前的候选解或可行解为S。考虑在S中包含k,如果可以将它包括进来,则将当前解更新为Union(S, k)。

3. 重复上述过程,直到S被填满或D被用完为止。

本文摘编自《程序员必会的40种算法》,经出版方授权发布

转载请联系微信:Better_lydia

RECOMMEND

推荐阅读

1be26e732e1f57a53e55c83fa3fc91a1.png

《程序员必会的40种算法》

9580024ce62055cfa8afa666f3ad92a5.png

作者:[加] 伊姆兰·艾哈迈德(Imran Ahmad)

译者:赵海霞

本书致力于利用算法求解实际问题

帮助初学者理解算法背后的逻辑和数学知识

推荐阅读

算法一直在计算科学和计算实践中发挥着重要作用。除了传统计算之外,使用算法解决现实问题的能力是开发人员和程序员必须具备的一项重要技能。本书不仅能帮助你拓展技能,选择强有力的算法解决现实世界的问题,还能帮助你了解算法原理。

本书内容丰富,涉及算法基础、设计技术、分析方法、排序算法、查找算法、图算法、线性规划算法、机器学习算法、推荐算法、数据算法、密码算法和并行算法等内容,重点讲述如何使用Python进行算法实现和算法性能的比较与分析。

d9d78de213a800f8af0b0e6c9b6e6efa.gif

851646334adb98d7d2dc5be1fce27cde.png

扫码关注【华章计算机】视频号

每天来听华章哥讲书

b433ac3b0b7362b230ef54bfb7b88109.gif

更多精彩回顾

干货 |C++都有哪些就业方向?是否应该学习C++?

书单 | 成为优秀Java开发者,我看了这几本书

上新 |《Core Java》作者亲授视频免费看,学习Java更轻松

资讯 |提升研发效能:抵制无效加班文化

资讯 | 又又叒更新,Win 12要来了?

干货 |一文带你掌握计算机体系结构核心内容

干货 | 机器人与人工智能的关系,终于有人讲明白了

书讯 | 2月书讯(下)| 新年到,新书到!

书讯 | 2月书讯 (上)| 新年到,新书到!

【赠书】【第96期】夯实基础,突破内卷,不被优化

5ff8ff015e3eef4b66005ec1c612167c.gif

54b9756a8fee27e9b6b0ba1699540a8b.gif

点击阅读全文购买

相关文章:

  • AI 是否拥有意识?从意识的定义说起
  • 百万在线:大型游戏服务端开发
  • ​什么是bug?bug的源头在哪里?
  • 【第97期】2022 软件工程师状况报告:Go 最抢手
  • Web渗透测试实战:基于Metasploit 5.0
  • 详解六种常见的上下文切换场景
  • 终于有人把Knative讲明白了
  • 赵宏田:用户画像场景与技术实现
  • 商品中台的可视化微前端实践
  • 4月书讯(下)| 上新了,华章
  • 场景拆解六步设计法,手把手教你细化场景
  • 2021年图灵奖出炉!高性能计算鼻祖Jack Dongarra获奖
  • ​香农与信息论三大定律
  • 【第98期】终于有人把Flink设计理念与基本架构讲明白了
  • Koa在实际的业务场景中,路由如何做分割?
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • CSS相对定位
  • Javascript弹出层-初探
  • Java面向对象及其三大特征
  • Linux中的硬链接与软链接
  • MySQL QA
  • PHP 的 SAPI 是个什么东西
  • 动态规划入门(以爬楼梯为例)
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 区块链将重新定义世界
  • 协程
  • 白色的风信子
  • 《天龙八部3D》Unity技术方案揭秘
  • 阿里云服务器如何修改远程端口?
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • (07)Hive——窗口函数详解
  • (26)4.7 字符函数和字符串函数
  • (70min)字节暑假实习二面(已挂)
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (蓝桥杯每日一题)love
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (五)c52学习之旅-静态数码管
  • (转)母版页和相对路径
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .java 9 找不到符号_java找不到符号
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .net core webapi 大文件上传到wwwroot文件夹
  • .Net IE10 _doPostBack 未定义
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .net 后台导出excel ,word
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例