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

【算法设计技巧】分治算法

分治算法

用于设计算法的另一种常用技巧为分治算法(divide and conquer)。分治算法由两部分组成:

  • 分(divide):递归解决较小的问题(当然,基准情况除外)
  • 治(conquer):然后,从子问题的解构建原问题的解。

传统上,在其代码中至少含有两个递归调用的例程叫作分治算法,且一般认为子问题是不相交的(即基本上不重叠)。例如,最大子序列和问题的一个 O(N logN) 的解法,以及分治算法的经典例子:归并排序 和 快速排序,它们分别有 O(N logN) 的最坏情形以及平均时间的时间界。

分治算法的运行时间

有效的分治算法都是把问题分成一些子问题,每个子问题都是原问题的一部分,然后进行某些附加的工作以算出最后的答案。例如,归并排序对两个问题进行运算,每个问题均为原问题大小的一半,然后用到 O(N) 的附加工作。由此得到运行时间方程(带有合适初始条件):

T(N) = 2T(N/2) + O(N)

该方程的解为 O(N logN)。下面的定理可以用来确定大部分分治算法的运行时间。

方程 T(N) = aT(N/b) + O(Nk) 的解为
在这里插入图片描述
其中 a ≥ 1 以及 b >1。

最近点问题

问题的输入是平面上的点集 P。如果 p1 = (x1, y1) 和 p2 = (x2, y2),那么 p1 和 p2 间的欧几里得距离为 [ (x1 - x2)2 + (y1 - y2)2 ]1/2 。需要找出一对最近的点。这其中有可能两个点位于相同的位置,在这种情况下它们的距离为 0。

如果存在 N 个点,那么就存在 N(N-1)/2 对点间的距离。

第一种方法是检查所有这些距离,能够得到一个很短的程序,但却是花费 O(N2) 的算法,也就是穷举搜索的算法。

//计算点对间最小距离的蛮力算法
//计算点对间最小距离的蛮力算法
for (i = 0; i < numPointsInStrip; ++i)for (j = i + 1; j < numPointsInStrip; ++j)if (dist(pi, pj) < δ)δ = dist(pi, pj);

假设平面上这些点已经按照 x 的坐标排过序,这只不过顶多在最后的时间界上仅加了 O(N logN) 而已,因为整个算法都将是 O(N logN) 的,所以排序基本上没增加运行时间消耗级别。

图1 画出了一个小的样本点集 P。若这些点已按 x 坐标排序,那我们可以画一条想象的垂线,把 P 分成两半:PL 和 PR
在这里插入图片描述
最近的一对点或者都在 PL 中,或者都在 PR 中,或者一个点在 PL 中而另一个在 PR 中。这三个距离在图2 中标出。
在这里插入图片描述
我们可以递归地计算 dL 和 dR。由于想要一个 O(N logN) 的解,因此必须能够只用 O(N) 的附加工作计算出 dC 。即,如果一个过程由两个一半大小的递归调用和附加的 O(N) 工作组成,那么总的时间将是 O(N logN)

令 δ = min (dL, dR)。如果 dC 对 δ 有所改进,那么只需计算 dC 。如果 dC 是这样一个距离,则决定 dC 的两个点必然在分割线的 δ 距离之内,把这个条形局域叫作带(strip)。如图3 所示,这个观察结果消减了需要考虑的点的个数(此例中的 δ = dR)。
在这里插入图片描述

有两种方法可以用来计算 dC,由于平均只有 O(N1/2) 个点在这个带中,因此第一种方法可以以 O(N2) 时间对这些点进行蛮力计算。但在最坏情况下,所有的点可能都在这条带状区域内,因此这种算法不总能以线性时间运行。

改进算法:确定 dC 的两个点的 y 坐标之间相差最多是 δ,否则就会有 dC > δ。设带中的点按照它们的 y 坐标排序。因此,如果 pi 和 pj 的 y 坐标相差大于 δ,则可以再去继续处理 pi+1

//最小距离的精化计算
for (i = 0; i < numPointsInStrip; ++i)for (j = i + 1; j < numPointsInStrip; ++j)if(pi and pj 's y-coordinates differ by more than δ)break; //转向下一个pielseif (dist(pi, pj) < δ)δ = dist(pi, pj);

选择问题

选择问题要求我们找出 N 个元素集合 S 中的第 k 个最小的元素。

基本的算法是简单的递归策略。设 N 大于截止点(cutoff point),元素将从截止点开始进行简单的排序,v 是选出的一个元素,叫作枢纽元(pivot)。其余元素被放在两个集合 S1S2 中,S1 含有那些保证不大于 v 的元素,而 S2 包含那些不小于 v 的元素。最后,如果 k ≤ |S1|,那么 S 中的第 k 个最小的元素就可以通过递归地计算 S1 中第 k 个最小的元素而找到。如果 k = |S1| +1,则枢纽元就是第 k 个最小的元素。否则,在 S 中的第 k 个最小的元素是 S2 中的第 (k - |S1| - 1) 个最小元素。这个算法和快速排序之间的主要区别在于,这里只有一个子问题而不是两个子问题要被求解。

五元中值组取中值分割法

对于快速排序,枢纽元一种好的选择是选取 3 个元素并取它们的中位数。但它并不提供一种好的保证。为得到一个好的最坏情形,关键想法是再用一个间接层。不是从随机元素的样本中找出中值,而是从一些中值的样本中找出中值。

基本的枢纽元选择算法如下:

  1. N 个元素分成 ⌊N/5⌋ 组,每组5个元素,忽略剩余的(最多4个)元素。
  2. 找出每组的中值,得到 ⌊N/5⌋ 个中值的表M
  3. 再求出 M 的中值,将其作为枢纽元 v 返回。

使用五元中值组取中值分割法的快速选择算法的运行时间为 O(N)

整数相乘

设要将两个 N 位数字的数 X 和 Y 相乘,并假设它们都是正的。几乎人在手算时用的算法都需要 O(N2) 次运算,这是因为 X 中的每一位数字都要被 Y 的每一位数字去乘。

如果 X = 61 438 521 而 Y = 94 736 407,那么 XY = 5 820 464 730 934 047。将 X 和 Y 拆成两半,分别由最高几位和最低几位数字组成。此时,XL = 6143,XR = 8521,YL = 9473,YR = 6407。则有 X = XL104 + XR 以及 Y = YL104 +YR,由此得

    XY = XLYL108 + (XLYR + XRYL)104 + XRYR

这个方程由4次乘法组成,即XLYL、XLYR、 XRYL 和 XRYR。它们每一个都是原问题大小的一半(N/2位数字)。若递归地使用该算法进行这4项运算,则得到递归

    T(N)=4T(N/2) +O(N)

可知T(N) = O(N2),为得到一个亚二次的算法,必须使用少于4次的递归调用,有

    XLYR + XRYL = (XL - XR) (YR - YL) + XLYL +XRYR

此时的递归方程

    T(N)=3T(N/2) +O(N)

从而得到 T(N) = O(N1.59)

相关文章:

【算法设计技巧】分治算法

分治算法 用于设计算法的另一种常用技巧为分治算法(divide and conquer)。分治算法由两部分组成&#xff1a; 分(divide)&#xff1a;递归解决较小的问题(当然&#xff0c;基准情况除外)治(conquer)&#xff1a;然后&#xff0c;从子问题的解构建原问题的解。 传统上&#x…...

已解决kettle新建作业,点击保存抛出异常Invalid state, the Connection object is closed.

已解决kettle新建作业&#xff0c;点击保存进资源数据库抛出异常Invalid state, the Connection object is closed.的解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 文章目录报错问题报错翻译报错原因解决方法联系博主免费帮忙解决报错报错问题 一个小伙伴…...

【设计模式】 工厂模式介绍及C代码实现

【设计模式】 工厂模式介绍及C代码实现 背景 在软件系统中&#xff0c;经常面临着创建对象的工作&#xff1b;由于需求的变化&#xff0c;需要创建的对象的具体类型经常变化。 如何应对这种变化&#xff1f;如何绕过常规的对象创建方法(new)&#xff0c;提供一种“封装机制”来…...

深入浅出PaddlePaddle函数——paddle.arange

分类目录&#xff1a;《深入浅出PaddlePaddle函数》总目录 相关文章&#xff1a; 深入浅出TensorFlow2函数——tf.range 深入浅出Pytorch函数——torch.arange 深入浅出PaddlePaddle函数——paddle.arange 语法 paddle.arange(start0, endNone, step1, dtypeNone, nameNone…...

X86 ATT常用寄存器及其操作指令

X86 AT&T常用寄存器及其操作指令 常用寄存器 esp寄存器&#xff1a;当我们需要访问堆栈帧中的变量时&#xff0c;可以使用esp寄存器来获取堆栈帧的基址&#xff0c;以便能够正确地访问堆栈帧中的变量。ebp寄存器&#xff1a;当我们需要调用一个函数时&#xff0c;可以使用…...

Kotlin 高端玩法之DSL

如何在 kotlin 优雅的封装匿名内部类&#xff08;DSL、高阶函数&#xff09;匿名内部类在 Java 中是经常用到的一个特性&#xff0c;例如在 Android 开发中的各种 Listener&#xff0c;使用时也很简单&#xff0c;比如&#xff1a;//lambda button.setOnClickListener(v -> …...

理光M2701复印机载体初始化方法

理光M2701基本参数&#xff1a; 产品类型&#xff1a;数码复合机 颜色类型&#xff1a;黑白 复印速度&#xff1a;单面&#xff1a;27cpm 双面&#xff1a;16cpm 涵盖功能&#xff1a;复印、打印、扫描 网络功能&#xff1a;支持无线、有线网络打印 接口类型&#xff1a;USB2.0…...

2.25Maven的安装与配置

一.Mavenmaven是一个Java世界中,非常知名的"工程管理工具"/构建工具"核心功能:1.管理依赖在进行一个A 操作之前,要先进行一个B操作.依赖有的时候是很复杂的,而且是嵌套的2.构建/编译(也是在调用jdk)3. 打包把java代码给构建成jar或者warjar就是一个特殊的压缩包…...

《英雄编程体验课》第 12 课 | 递归

文章目录 零、写在前面一、搜索算法的原理二、深度优先搜索三、基于DFS的记忆化搜索四、基于DFS的剪枝五、基于DFS的A*(迭代加深,IDA*)零、写在前面 该章节节选自 《夜深人静写算法》,主要讲解最基础的搜索算法,其中用到的思想就是递归,当然,如果已经对本套体验课了如指…...

35测试不如狗?是你自己技术不够的怨怼罢了

一、做软件测试怎么样&#xff1f; 引用著名软件测试专家、清华大学郑人杰教授的说法&#xff1a;软件测试工程师是一个越老越吃香的职业。 其中就表达了软件测试工作相对稳定、对年龄没有限制、而且随着项目经验的不断增长和对行业背景的深入了解&#xff0c;会越老越吃香。…...

【代码训练营】day42 | 1049. 最后一块石头的重量 II 494. 目标和 474.一和零

所用代码 java 最后一块石头的重量II LeetCode 1049 题目链接&#xff1a;最后一块石头的重量II LeetCode 1049 - 中等 思路 无。 把石头分成重量总和近似两堆&#xff0c;然后两堆石头相撞&#xff0c;剩下的就是最小的石头。每个石头只能用一次&#xff0c;01背包&#xf…...

Golang协程常见面试题

协程面试题交替打印奇数和偶数N个协程打印1到maxVal交替打印字符和数字交替打印字符串三个协程打印ABCChannel练习交替打印奇数和偶数 下面让我们一起来看看golang当中常见的算法面试题 使用两个goroutine交替打印1-100之间的奇数和偶数, 输出时按照从小到大输出. 方法一&…...

种群多样性:智能优化算法求解基准测试函数F1-F23种群动态变化图(视频)

智能优化算法求解基准测试函数F1种群动态变化图智能优化算法求解基准测试函数F2种群动态变化图智能优化算法求解基准测试函数F3种群动态变化图智能优化算法求解基准测试函数F4种群动态变化图智能优化算法求解基准测试函数F5种群动态变化图智能优化算法求解基准测试函数F6种群动…...

Qt 中的XML

XML的基本介绍&#xff1a; 在前端开发中&#xff1a;HTML是用来显示数据&#xff0c;而XML是用来传输和存储数据的 XML 指可扩展标记语言&#xff08;EXtensible Markup Language&#xff09;XML 是一种标记语言&#xff0c;很类似 HTMLXML 的设计宗旨是传输数据&#xff0c;而…...

网络应用之URL

URL学习目标能够知道URL的组成部分1. URL的概念URL的英文全拼是(Uniform Resoure Locator),表达的意思是统一资源定位符&#xff0c;通俗理解就是网络资源地址&#xff0c;也就是我们常说的网址。2. URL的组成URL的样子:https://news.163.com/18/1122/10/E178J2O4000189FH.html…...

【Linux】重定向原理dup2缓冲区

文章目录重定向原理输出重定向关于FILE解释输出重定向原理追加重定向输入重定向dup2缓冲区语言级别的缓冲区内核缓冲区重定向原理 重定向的本质就是修改文件描述符下标对应的struct file*的内容 输出重定向 输出重定向就是把本来应该输出到显示器的数据重定向输出到另一个文…...

ROG配置ubuntu20.04.5双系统要点

win11ubuntu20.04.5 1. BIOS设置 开机长按F2进入bios设置&#xff0c;修改advanced参数&#xff1a; boot -> 关闭fast bootsecurity -> 关闭secure boot设置VMD controller为Disabled&#xff08;其他电脑是修改硬盘的SATA和ACHI模式&#xff09;。但是改了之后windo…...

机械革命旷世G16电脑开机变成绿屏了无法使用怎么办?

机械革命旷世G16电脑开机变成绿屏了无法使用怎么办&#xff1f;最近有用户使用的机械革命旷世G16电脑一开机之后&#xff0c;电脑屏幕就变成了绿色的&#xff0c;无法进行任何的操作。出现这个问题可能是因为电脑中病毒了&#xff0c;或者是系统出现故障。我们可以通过U盘来重新…...

python中关于time模块的讲解---指定格式时间字符串转为时间戳

本文章可以解决任意字符串格式时间转为时间戳 返回json格式 可以在此基础上进行修改 时间格式控制符 说明 %Y 四位数的年份&#xff0c;取值范围为0001~9999,如1900 %m 月份&#xff08;01~12&#xff09;&#xff0c;例如10 %d 月中的一天&#xff08;01~31&#xff09;例…...

MySql存储引擎与索引

MySql引擎 存储引擎是具体操作数据的地方&#xff0c;是一种对数据存储的技术与其配套的功能 不同存储引擎所采用存储的方式的不同&#xff0c;并且索引技巧与锁定水平也不同 根据业务的需求灵活的选择存储引擎即可满足的实际的需要 Innodb Innodb是MySql中的默认安装的引擎…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...