数据结构与算法笔记:基础篇 - 分治算法:谈一谈大规模计算框架MapReduce中的分治思想

news2024/11/20 0:30:04

概述

MapReduce 是 Google 大数据处理的三姐马车之一,另外两个事 GFS 和 Bigtable。它在倒排索引、PageRank 计算、网页分析等搜索引擎相关的技术中都有大量的应用。

尽管开发一个 MapReduce 看起来很高深。实际上,万变不离其宗,它的本质就是本章要学的这种算法思想,分支算法。


如何理解分支算法?

为什么说 MapReduce 的本质就是分治算法呢?先来看看什么事分治算法?

分治算法(divide and conquer)的核心思想其实就是四个字,分而治之,也就是将原问题划分成 n 个规模较小,并且结构与原问题相似的子问题,递归地解决这些子问题,然后再合并其结果,就得到原问题的解。

这个定义看起来有点类似递归地定义。关于分治和递归,我们在 排序(下) 的时候讲过,分治算法是一种处理问题的思想,递归是一种编程技巧。实际上,分治算法一般都比较适合用递归来实现。分治算法的递归实现中,每一次递归都会涉及三个操作:

  • 分解:将原问题分解为一系列子问题;
  • 解决:递归地求解各个子问题,若子问题足够小,则直接求解;
  • 合并:将子问题的结果合并成原问题。

分治算法能解决的问题,一般要满足以下几个条件:

  • 原问题与分解成的小问题具有相同的模式;
  • 原问题分解的子问题可以独立解决,子问题之间没有相关性,这一点是分治算法跟动态规划的明显区别,等讲到动态规划,会详细对比这两种算法;
  • 具有分解终止条件,也就是说,当问题足够小时,可以直接求解;
  • 可以将子问题合并成原问题,而这个合并操作的复杂度不能太高,否则就起不到减少算法总体复杂度的效果了。

分治算法应用举例分析

理解分治算法的原理并不难,但是要想灵活应用并不容易。所以,接下来,我会带你用分治算法解决我们在讲排序的时候设计的一个问题,加深你对分治算法的理解。

还记得我们在排序算法里讲到的数据的有序度、逆序度的概念吗?我当时讲到,我们用有序度表示一组数据的有序程度,用逆序度表示一组数据的无序程度。

假设我们有 n 哥数据,我们期望数据从小到大排列,那完全有序的数据的有序度就是 n(n-1)/2,逆序度等于 0;相反,倒序排列的数据的有序度就是 0,逆序度就是 n(n-1)/2。除了这两种极端情况外,我们通过计算有序对或逆序对的个数,来表述数据的有序度或逆序度。

在这里插入图片描述

现在的问题是,如何编码求出一组数据的有序对个数或者逆序对个数呢? 因为有序对个数和逆序对个数的求解方式是类似的,所以你可以之思考逆序对个数的求解方法。

最笨的方法是,拿每个数组跟它后面的数字比较,看看有几个比它小。我们把比它小的数字的个数记作 k,通过这样的方式,把每个数字都考察一遍之后,然后对每个数字对应的 k 值求和,最后得到的总和就是逆序对个数。不过,这样擦做的时间复杂度是 O ( n 2 ) O(n^2) O(n2)。有没有更加高效的处理方法呢?

我们用分治法来试试。我们套用分治法的思想来求数组 A 的逆序对个数。我们可以将数组分成前后两半 A1 和 A2,分别计算 A1 和 A2 之间的逆序对个数 K1 和 K2,然后再计算 A1 和 A2 之间逆序对个数 K3。那数组 A 的逆序对个数就等于 K1+K2+K3。

我们前面讲过,使用分治算法其中一个要求是,子问题合并的代价不能太大,否则就起不到了降低时间复杂度的效果了。那回到这个问题,如何快速计算出两个子问题 A1 与 A2 之间的逆序对个数呢?

这里就要借助归并排序算法了。你可以先试着想想,如何借助归并排序算法来解决呢?

归并排序中有一个非常关键的操作,就是将两个有序的小数组,合并成一个有序的数组。实际上,在这个合并的过程中,我们就可以计算这连个小数组的逆序对个数了。每次合并操作,我们都计算逆序对个数,把这些计算出来的逆序对个数求和,就是这个数组的逆序对个数了。

在这里插入图片描述

尽管画了张图来解释,但个人觉得,对于工程师来说,看代码更好理解一些,所以我们把这个过程翻译成了代码,你可以结合着图和文字描述一起看下。

    private int num = 0; // 全局变量或成员变量

    public int count(int[] a, int n) {
        num = 0;
        mergeSortCounting(a, 0, n-1);
        return num;
    }

    private void mergeSortCounting(int[] a, int p, int r) {
        if (p >= r) return;
        int q = (p + r) / 2;
        mergeSortCounting(a, p, q);
        mergeSortCounting(a, q+1, r);
        merge(a, p, q, r);
    }

    private void merge(int[] a, int p, int q, int r) {
        int i = p, j = q+1, k = 0;
        int[] tmp = new int[r-p+1];
        while (i <= q && j <= r) {
            if (a[i] < a[j]) {
                tmp[k++] = a[i++];
            } else {
                num += (q-i+1); // 统计p~q之间比a[j]大的元素的个数
                tmp[k++] = a[i++];
            }
        }
        while (i <= q) { // 处理剩下的
            tmp[k++] = a[i++];
        }
        while (j <= r) { // 处理剩下的
            tmp[k++] = a[j++];
        }
        for (i = 0; i <= r-p; i++) { // 从tmp拷贝回a
            a[p+i] = tmp[i];
        }
    }

很多同学经常会说,某某算法思想如此巧妙,我是怎么也想不到的。实际上,确实是的。有些算法确实非常巧妙,并不是每个人短时间都能想到的。比如这个问题,并不是每个人都能想到可以借助归并排序算法来解决。不夸张地说,如果之前没接触过,觉得部分人都想不到。但是,如果我告诉你可以借助归并排序算法来解决,那你就应该想到如何改造归并排序,来求解这个问题了,只要你能做到这一点,我觉得就很棒了。

关于分治算法,还有两道比较经典的问题:

  • 二维平面上有 n 个点,如何快速计算出两个距离最近的点对?
  • 有两个 nn 的矩阵 A,B,如何快速求解两个矩阵的成绩 C=AB?

分治思想在海量数据处理中的应用

分治算法思想的应用是非常广发的,并不仅限于指导编程和算法设计。它还经常用在海量数据处理的场景中。我们前面讲的数据结构和算法,大部分都是基于内存存储和单机处理。但是,如果要处理的数据量非常大,没法一次性放到内存中,这个时候,这些数据结构和算法就无法工作了。

比如,给 10GB 订单文件按照金额排序这样一个需求,看似是一个很简单的排序问题,但是因为数据量大,有 10GB,而我们机器的内存可能只有 2、3GB 这样子,无法一次性加载到内存,也就无法通过单纯地使用快排、归并排序等基础算法来解决了。

要解决这种数据量大到内存装不下的问题,我们就可以利用分治的思想。我们可以将海量的数据集合根据某种方法,划分为几个小的数据集合,每个小的数据集合单独加载到内存来解决,然后再将小数据集合合并成大数据集合。实际上,利用这种分治的处理思路,不仅仅能克服内存的限制,还能利用多线程或者多机处理,加快处理的速度。

比如刚刚的例子,给 10GB 的订单排序,我们可以先扫描一遍订单,根据订单的金额,将 10GB 的文件划分为几个金额区间。比如订单金额 1 到 100 元的放到一个小文件,101 到 200 的放到另一个文件,以此类推。这样每个小文件都可以单独加载到内存排序,最后将这些有序的小文件合并,就是最终有序的 10GB 订单数据了。

如果订单存储在类似 GFS 这样的分布式系统上,当 10GB 订单被划分成多个小文件的时候,每个文件可以并行加载到多态机器上处理,最后再将结果合并在一起,这样并行处理的速度也加快了很多。不过,这里有一点要注意,就是数据的存储与计算所在的机器是同一个或在网络中靠的很近(比如一个局域网内,数据存取速度很快),否则就会因为数据访问的速度,导致整个处理过程不但不会变快,反而有可能变慢。

你可能还有印象,这个就是我们在讲线性排序的时候举的例子。实际上,在前面已经学习的课程中,还讲了很多利用分治算法来解决的问题。

谈一谈大规模计算框架MapReduce中的分治思想

刚刚举的订单的例子,数据有 10GB 大小,可能给你的感受还不强烈。那如果我们要处理的数据时 1T、10T、100T 这样的数据,那一台机器处理的效率肯定是非常低的。而对于谷歌搜索引擎来说,网页爬取、清洗、分析、分词、计算权重、倒排索引等等各个环节中,都会面对如此海量的数据(比如网页)。所以利用集群并行处理显然是大势所趋。

一台机器过于低效,那我们就把人去拆分到多态机器上来处理。如果拆分之后的小人物之间互不干扰,独立计算,最后再将结果合并。这不就是分治思想吗?

实际上,MapReduce 框架只是一个任务调度器,底层依赖 GFS 来存储数据,依赖 Borg 管理机器。它从 GFS 中拿数据,交给 Brog 中的机器执行,并且时刻监控机器执行的进度,一旦机器出现宕机、进度卡壳等,就重新从 Brog 中调度一台机器执行。

尽管 MapReduce 的模型非常简单,但是在 Google 内部应用非常广泛。它除了可以用来处理这种数据与数据之间存在关系的任务,比如 MapReduce 的经典例子,统计文件中单词出现的频率。此外,它还可以用来处理数据与数据之间没有关系的任务,比如对网页分析、分词等,每个网页可独立的分析、分词,而这两个网页之间没有关系。网页几十亿、上百亿,如果单机处理,效率地下,我们就可以利用 MapReduce 提供可靠、高性能、高容错的并行计算框架,并行地处理这几十亿、上百亿的网页。

小结

本章讲了一种应用非常广泛的算法思想,分治算法。

分治算法用四个字概况就是 “分而治之”,将原问题划分成几个规模较小而结构与原问题相似的子问题,递归地解决这些子问题,然后再合并其结果,就得到原问题的解。这个思想非常简单、好理解。

本章讲解了两种分治算法的经典的应用场景,一个是用来指导编码,降低问题求解的时间复杂度,另一个是解决海量数据处理问题。比如 MapReduce 本质上就是利用了分治思想。

我们也时常感叹 Google 的创新能力如此之强,总是在引领技术的发展。实际上,创新并非离我们很远,创新的源泉来自对事物本质的认识。无数优秀架构设计的思想来源都是基础的数据结构和算法,这本身就是算法的一个魅力所在。

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

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

相关文章

【nginx】 nginx核心功能

【nginx】 nginx核心功能 1.nginx核心功能 1. 反向代理 2. 负载均衡 3. 动静分离 4. nginx的高可用2. 反向代理 正向代理: 该服务器代理的是客户端&#xff0c;对于服务器来说&#xff0c;不知道真实客户端的ip。比如: 翻墙软件。 访问国外的服务器---使用了翻墙软件----对…

响应式高端网站模板源码图库素材 资源下载平台源码

源码介绍 亲测可用&#xff0c;可用于做娱乐网资源网&#xff0c;功能非常的齐全无任何加密也无任何后门&#xff01;响应式高端网站模板源码图库素材 资源下载平台源码&#xff08;可运营&#xff09; 页面很美观&#xff0c;堪比大型网站的美工&#xff0c;而且页面做的也很…

GRIT论文阅读笔记

一篇试图统一生成任务和编码任务的工作&#xff0c;就是把只能完成生成任务的GPT改成既能生成又能encode。思路其实很简单&#xff0c;就是在输入的时候添加instruction tokens来指引模型做representation还是generation&#xff0c;然后各自算损失。representation任务用的是d…

【操作系统】操作系统实验02-生产者消费者程序改进

1. 说明文档中原有程序实现的功能、实现方法。&#xff08;用语言、程序流程图、为原有程序添加注释等方式均可&#xff09; 1.//const.h 2.//定义宏变量 3.#ifndef CONST_H 4.#define CONST_H 5. 6.#define TRUE 1 7.#define FALSE 0 8.#define ERROR 0 9.#define OVERFLOW -…

据阿谱尔APO Research调研显示,2023年全球水凝胶市场销售额约为14.2亿美元

根据阿谱尔 (APO Research&#xff09;的统计及预测&#xff0c;2023年全球水凝胶市场销售额约为14.2亿美元&#xff0c;预计在2024-2030年预测期内将以超过5.0%的CAGR&#xff08;年复合增长率&#xff09;增长。 水凝胶有多种应用&#xff0c;包括个人护理、制药、农业及其他…

界面组件Kendo UI for Angular 2024 Q2亮点 - 让应用程序界面拥有AI提示

随着最新的2024年第二季度发布&#xff0c;Kendo UI for Angular为应用程序开发设定了标准&#xff0c;包括生成式AI集成、增强的设计系统功能和可访问的数据可视化。新的2024年第二季度版本为应用程序界面提供了人工智能(AI)提示&#xff0c;从设计到代码的生产力增强、可访问…

卷积神经网络(CNN)理解

1、引言&#xff08;卷积概念&#xff09; 在介绍CNN中卷积概念之前&#xff0c;先介绍一个数字图像中“边缘检测edge detection”案例&#xff0c;以加深对卷积的认识。图中为大小8X8的灰度图片&#xff0c;图片中数值表示该像素的灰度值。像素值越大&#xff0c;颜色越亮&…

ByteTrack跟踪理解

1.ByteTrack 核心思路 &#xff08;1&#xff09;区分高置信度检测框与低置信度检测框&#xff0c;不同置信度检测框采取不同处理方式。 &#xff08;2&#xff09;保留低置信度检测框&#xff0c;在后续可能会重新确认为 confirm 状态。而不是像传统 MOT 算法选择删除。 2.…

视频行人搜索 (Person Search in Videos)

文章目录 视频行人搜索 (Person Search in Videos)图像行人搜索存在问题Video PS 定义MTA-PS数据集First person search dataset in videosComplicated ambient conditions and realistic monitoring scenariosPrivacy insensitivity 方法 视频行人搜索 (Person Search in Vide…

Nacos从入门到实战

一、Nacos介绍 1.什么是Nacos 官方&#xff1a;一个更易于构建云原生应用的动态服务发现&#xff08;Nacos Discovery&#xff09;、服务配置&#xff08;Nacos Config&#xff09;和服务管理平台 集 注册中心配置中心服务管理 平台 注册中心&#xff1a;把所有的服务注册进去…

Redis变慢了?

Redis变慢了&#xff1f; 什么是Redis&#xff1f;测定Redis变慢&#xff1f;最大响应延迟平均响应延迟设置Redis慢日志 分析Redis变慢bigkeysbigkey的危害bigkey优化 写在最后 什么是Redis&#xff1f; 作为一个技术人员来说&#xff0c;大家用的最多的可能就是Redis了&#…

BottomSheet 半模态视图

先看效果图: 越来越多的app,使用半模态视图,弹窗从底部弹窗,手动滑动收起。交互流程丝滑,体验流畅。我这一研究才发现,官方出了一个控件叫 UISheetPresentationController,使用起来及其方便,只需要关注业务逻辑就可以,着急的朋友可以直接把demo拿去。BottomSheetDemo…

Java new HashMap 指定容量,代码怎么写? 学习源码小记

之前针对 创建map 指定容量&#xff0c;写过一篇吐槽教学文章&#xff1a;HashMap 使用的时候指定容量&#xff1f;你真的用明白了吗&#xff1f;&#xff08;值得一阅&#xff09;_new hashmap<>(4);-CSDN博客 因为我们经常要通过代码做一些数据的分组&#xff0c;比如查…

第二证券股市资讯:昨夜!全球新“股王”诞生

昨晚&#xff0c;英伟达成全球市值榜首公司。 当地时间6月18日&#xff0c;美股三大指数小幅收高&#xff0c;标普500指数与纳指再创前史新高。标普500指数涨0.25%&#xff0c;道指涨0.15%&#xff0c;纳指涨0.03%。 AI热潮推动英伟达大涨&#xff0c;市值逾越微软、苹果&…

jsp运行提示_jsp.java某行存在错误问题的解决

jsp运行提示XXX_jsp.java某行存在错误问题的解决 在编译运行jsp文件时&#xff0c;出现类似如下提示&#xff1a; 49行发生错误&#xff0c;要注意&#xff1a; 这里所指的49行并非jsp文件的第49行&#xff0c;而是编译后的jsp.java文件的第49行。 因此&#xff1a;解决问题…

国际导师上海面授大规模敏捷LeSS认证2024年8月22-24日开班 | 报名享特大福利

课堂互动练习 学员反馈 • “LeSS课我正经听过的有3次&#xff1b;两次Bas Vodde主讲&#xff0c;一次吕毅老师主讲。第一次应该是2015年&#xff0c;这门课中体现的对组织运作和产品开发底层逻辑的洞见令我折服。后来又陆续听了两次&#xff0c;每次都有更多体会。 我试着从一…

Linux中git无法提交,出现不知道身份时的错误,无法检测到有效的电子邮件地址以关联代码的提交

在输入 git commit -m "日志信息"时&#xff0c;出现下列问题。 这是因为Git无法检测到有效的电子邮件地址以关联代码的提交。 一、设置用户邮箱和用户名 使用以下命令来设置你的用户邮箱和用户名。请确保将youexample.com替换为你的实际邮箱地址&#xff0c;并将Y…

2024香港人才引进计划有哪些?申请条件、政策、利弊一次性说清楚

2024香港人才引进计划有哪些&#xff1f; 拥有香港身份&#xff0c;不仅可以享受到优质的教育资源、税收优惠、以及国际化的商业环境&#xff0c;还能在金融、商业、法律保障和生活品质等方面获得显著的好处。 而这&#xff0c;也是很多内地精英人群&#xff0c;通过申请香港…

公有云_私有云_云平台_服务器安全组_按量付费_vpc私有网络/专有网络原理---分布式云原生部署架构搭建005

云平台的概念 有很多不是很重要的就直接略过了,只留下重要的内容. 公有云的优点.对安全性要求高的不让用公有云 混合云,一部分业务放到公有云上,一部分放到私有云上. 上面的软件是用来远程连接用的,现在 来看一个如何开通阿里云的ecs服务器,非常简单,没什么可说的. 点击实例

白酒:酒文化与艺术创作的结合

酒文化与艺术创作在历史长河中相互交融&#xff0c;共同发展。云仓酒庄的豪迈白酒作为中国的酒的品牌&#xff0c;以其与众不同的口感和品质&#xff0c;成为了艺术创作的重要灵感来源。 首先&#xff0c;豪迈白酒的酿造技艺本身就是一种与众不同的艺术。酿酒师傅们在传承古老技…