[算法分析与设计] 3. 并查集分析与反阿克曼函数

这篇具有很好参考价值的文章主要介绍了[算法分析与设计] 3. 并查集分析与反阿克曼函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Union-Find 问题:给定 \(n\) 个元素,最初每个元素在一个集合中,有两种操作,union 表示合并两个集合,find 表示查询某个特定元素所在的集合。

并查集是一种数据结构。其为每个集合寻找一个代表元,代表元可以是任意的,也可以随操作变化,但需要满足任何时刻一个集合的代表元是确定且唯一的。数据结构支持 MakeSet, Find, Union 三种操作,表示新建一个仅包含一个元素的集合、寻找一个集合的代表元、合并两个元素所在的集合。

Up-tree 是并查集最常用的实现方式,其将每个集合的元素维护为一棵有根树,将根作为这个集合的代表元,Union 时通过将一个根连到另一个根上将两棵树合并为一棵,Find 时不断爬父亲找根即可。

\(n\) 为元素个数,\(m\) 为操作次数。

Union 总是 \(O(1)\) 的,关键在于 Find。什么都不做是 \(O(n)\) 的。有两种优化,按秩合并和路径压缩。按秩合并是守序善良的 \(\log\) 数据结构。带按秩合并的路径压缩是难分析的。

需要注意的是 Find 一个点的复杂度为这个点所在集合改变代表元的次数。

有两种常用的秩的定义方法,高度 Height 和重量 Weight。合并时总是将秩小的根连到秩大的根上。如果是高度,则秩增大 \(1\) 当且仅当两个集合秩相同,因此可以归纳证明秩为 \(k\) 至少需要 \(2^k\) 个点(达到下界的是二项树),因此每个点至多更换 \(\log\) 次代表元,复杂度为单次严格 \(O(\log n)\)。重量同理。

路径压缩在每次 Find 时将涉及到的一条链打散,所有点直接挂在根上,这个操作不会额外增加复杂度。

如果按秩合并和路径压缩同时使用,那基于高度的秩将不方便维护。不过我们可以修改其定义,Find 时秩不改变,Union 时只有两者秩相同则新的根的秩增加一,旧的不变,否则小的合并到大的上,两者都不变。我们来分析其复杂度。

随着操作进行,对于每个 \(x\)\(\mathrm{rank}(x)\) 只增不减。当 \(x\) 不为根时,\(\mathrm{rank}(x)\) 不再改变。如果 \(y\)\(x\) 的父亲,\(\mathrm{rank}(y) > \mathrm{rank}(x)\)。对于 \(\mathrm{rank} \geq r\) 的结点任何时候至多 \(\frac {\min(n, m)}{2^r}\) 个。

\(T(m, r)\) 表示 \(m\) 个操作,秩 \(< r\) 的复杂度,令 \(s\) 为秩的一个阈值。考虑路径压缩时 \(x\) 被挂在了新父亲 \(y\) 上。

  • \(\mathrm{rank}(x), \mathrm{rank}(y) < s\),则归档到 \(T(m_0, s)\) 中。
  • \(\mathrm{rank}(x), \mathrm{rank}(y) \geq s\),共涉及 \(\frac m{2^s}\) 个结点,总复杂度 \(T(m_1, r) = O(\frac{m}{2^s}r)\)
  • \(\mathrm{rank}(x) < s \leq \mathrm{rank}(y)\),再分两种情况
    • \(\mathrm{rank}(\mathrm{parent}(x)) < s\),则经过一次操作后 \(\mathrm{rank}(\mathrm{parent}(x)) = \mathrm{rank}(y) \geq s\),因此总复杂度 \(O(m)\)
    • \(\mathrm{rank}(\mathrm{parent}(x)) \geq s\),每次 Find 只会有一个这样的 \(x\),因此为每次 Find 增加 \(O(1)\)

所以,我们得到

\[T(m, r) \leq T(m, s) + O\left(\frac m{2^s} r + m\right) \]

\(s = \log r\),则有

\[T(m, r) \leq T(m, \log r) + O(m) \]

因此,只需要递归 \(\log^* r\) 层,所以

\[T(m, r) = O(m \log^* r) \]

回到

  • \(\mathrm{rank}(x), \mathrm{rank}(y) \geq s\),共有 \(\frac m{2^s}\) 个结点,总复杂度 \(T(m_1, r) = O(\frac{m}{2^s}r)\)

我们将其优化为了 \(O(\frac{m}{2^s}\log^* r)\)。因此重新写

\[T(m, r) \leq T(m, s) + O\left(\frac m{2^s} \log^*r + m\right) \]

\(s = \log^{**}r\),即迭代 \(\log^*\) 多少次 \(r\) 后到一个常数,则可以得到

\[T(m, s) = O(m \log^{**} r) \]

等等等等,所以对任何常数 \(k\)

\[T(m, s) = O(m \log^{*^{(k)}} r) \]

但是由于递归是非常数,或称 \(\omega(1)\) 轮的,所以不能直接认最终复杂度为 \(O(m)\),一个常数经过 \(\omega(1)\) 轮递归后可能叠加为 \(\omega(1)\)。我们需要精确分析常数。

最初

\[T(m, r) \leq m\cdot r \]
\[T(m, r) \leq T(m, s) + \frac m{2^s}r + m \]

\(s = \log r\),则

\[T(m, r) \leq T(m, \log r) + 2m \]
\[T(m, r) \leq 2m \log^* r \]
\[T(m, r) \leq T(m, s) + 2 \frac m{2^s}\log^* r + m \]
\[T(m, r) \leq 3m \log^{**}r \]

以此类推,最终得到

\[T(m, r) = O(km \log^{*^{(k)}} r) \]

\(k = \alpha(n)\)\(\log^{*^{(k)}} r\) 归为常数,最终复杂度为 \(O(m \alpha(n))\)

其中 \(\alpha\) 为反阿克曼函数,\(\alpha(n) = \min\{k \mid A(k, 1) \geq n\}\),其中 \(A\) 为阿克曼函数。阿克曼函数是这样定义的:

\[A(m, n) = \begin{cases} n + 1 && m = 0 \\ A(m - 1, 1) && m > 0, n = 0 \\ A(m - 1, A(m, n - 1)) && m > 0, n > 0\end{cases} \]
\[\begin{aligned} A(0, n) &= n + 1 \\ A(1, n) &= 2 + (n + 3) - 3 \\ A(2, n) &= 2 \times (n + 3) - 3 \\ A(3, n) &= 2^{n + 3} - 3 \\ A(4, n) &= \underbrace{2^{2^{2^{\ldots^2}}}}_{n + 3} - 3 \\ &\vdots \\ \end{aligned}\]

可知其是将上一个值 \(A(m, n - 1)\) 作为在第 \(m - 1\) 行的递归轮数,因此 \(m\) 充当的是递归形式的阶次。

其比任何多项式和指数函数增长得都要快。因此 \(\alpha(n)\) 比任何 \(\log^{***\ldots **}\) 增长得都要慢。但其不是常数,\(\lim_{n \to +\infty}\alpha(n) \to +\infty\)

不难发现 \(\log^{*^{(k)}}\) 表示的是经过多少次 \(k - 1\) 阶递归能到一个常数,和 \(A\) 的定义恰好相对。\(\alpha(n) \approx \min\left\{k \mid \log^{*^{(k)}} \leq 3\right\}\)

  • Up-tree 实现的并查集复杂度为 \(\Omega(m \alpha(n))\)。[Tarjan, '75]

  • Union-Find 问题的下界为 \(\Omega(\alpha(n))\)。[Fredman, Saks '89]

接下来介绍另一个 \(\alpha\) 在复杂度中出现的问题,区间半群查询。

\(n\) 个元素 \(A_1, A_2, \ldots, A_n \in (G, +)\) 排成一行,每次查询 \(i, j\),求 \(\sum_{q=i}^j A_q\)。半群意味着不能使用前缀和相减(因为没有加法逆元)等手段,只有加法封闭和结合律两条性质。要求使用尽可能少的存储量,使得每次查询时只使用至多 \(k\) 次加法。设 \(S_k(n)\) 表示最少存储量。

\[S_0(n) = \frac 12n(n-1) \]

\(S_1(n)\),序列分治得到

\[S_1(n) = n \log n \]

\(S_3(n)\),递归四毛子,第一层块大小 \(B = \log n\),对每个块存前后缀,块间用 \(S_1\),块内递归 \(S_3\) 得到

\[S_3(n) \leq 2n + S_1\left(\frac n{\log n}\right) + \frac n{\log n} S_3(\log n) \]

其和之前的形式类似。可得

\[S_3(n) = 3n \log^* n \]

假设

\[S_{2k - 1}(n) \leq (2k - 1) n f(n) \]

其中 \(f(n)\) 为块大小,满足对 \(n\) 不降,则

\[S_{2k + 1}(n) \leq 2n + S_{2k - 1}\left(\frac n{f(n)}\right) + \frac n{f(n)} S_{2k + 1}(f(n)) \leq (2k + 1) n + \frac n{f(n)} S_{2k + 1}(f(n)) \]

归纳可得

\[S_{2k+1}(n) = (2k + 1)n f^*(n) \]

因此

\[S_{2k+1} \leq (2k + 1) n \log^{*^{(k)}} n \]
\[S_{2\alpha(n) + 1} = O(n\alpha(n)) \]

更进一步地有文章来源地址https://www.toymoban.com/news/detail-710976.html

  • 对于 \(O(\alpha(n))\) 次加法,\(O(n)\) 空间 [Yao; Chazelle, Rosenberg]。

到了这里,关于[算法分析与设计] 3. 并查集分析与反阿克曼函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Unity3D赛车游戏】【四】在Unity中添加阿克曼转向,下压力,质心会让汽车更稳定

    !在这里插入图片描述 👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity游戏demo – 😶‍🌫️版本: Unity2021 😶‍🌫️适合人群:Unity初学者 😶‍🌫️学习目标:3D赛车游戏的基础制

    2024年02月11日
    浏览(34)
  • 程序自动分析——并查集+离散化

    在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。考虑一个约束满足问题的简化版本:假设 x1,x2,x3,… 代表程序中出现的变量,给定 n 个形如 xi=xj 或 xi≠xj 的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所

    2024年02月11日
    浏览(27)
  • 并查集算法实现

    牛客测试链接 并查集(Disjoint Set)是一种用于处理集合合并与查询问题的数据结构。它支持两种操作:合并(Union)和查询(Find)。 合并操作将两个不相交的集合合并为一个集合,查询操作用于判断两个元素是否属于同一个集合。 本文将介绍并查集算法的实现,并给出一个

    2024年01月25日
    浏览(33)
  • 【数据结构与算法】并查集

    并查集是一个树形结构,所谓的并查,就是 当我们有了一个节点,我们就能知道这个节点属于哪个集合 。 举个例子理解以下:战国时期有很多国家,它们会互相打仗,那么现在有两个互相不认识的人,如何知道对方是敌是友呢? 现在有一种方法:每个国家都有一个大王,我

    2023年04月15日
    浏览(28)
  • Peter算法小课堂—并查集

    我们先来看太戈编程467题 攀亲戚 题目描述: 最近你发现自己和古代一个皇帝长得很像:都有两个鼻子一个眼睛,你想知道这皇帝是不是你的远方亲戚,你是不是皇亲国戚。目前你能掌握的信息有m条,关于n个人:第i条信息包含两个人的编号ai,bi,表示ai和bi是亲戚。你的编号

    2024年01月18日
    浏览(38)
  • 算法与数据结构(九)--并查集

    1.处理对象:Disjoint Set,即“不相交集合”。 在一些应用问题中,需将n个不同的元素划分成一组不相交的集合。开始时,每个元素自成一个单元素集合,然后按一定顺序将属于同一组元素的集合合并。其间要反复用到查询某个元素属于哪个集合的运算。适合于描述这类问题的

    2024年02月10日
    浏览(31)
  • 算法刷题day34:并查集

    今天写的题集是并查集,其实感觉有两个难点,一个是,要维护多余的信息和路径压缩,另一个难点则是抽象出来合并集合的这个操作,还是要不断地练习,看别人怎么去做,加油! 标签:并查集 思路: 模板题,没啥说的 题目描述: 示例代码: 标签:并查集 思路: 其实

    2024年03月21日
    浏览(57)
  • 【算法日志】图论 并查集及其简单应用

    并查集是一种算法设计思想,通过判断两个元素是否在同一个集合里,常用来解决一些和图相关的连通性问题。 并查集主要有以下两个功能: 将两个元素添加到一个集合中。 判断两个元素是否是在一个集合之中(这一功能够有效判断是否成环)。 主要思想: 通过创建一个数组

    2024年01月23日
    浏览(37)
  • ⌈算法进阶⌋图论::并查集——快速理解到熟练运用

    目录  一、原理 1. 初始化Init   2. 查询 find  3. 合并 union 二、代码模板 三、练习 1、  990.等式方程的可满足性🟢 2、  1061. 按字典序排列最小的等效字符串🟢 3、721.账户合并 🟡 4、  839.相似字符串组🟡 5、  2812.找出最安全路径 🔴 并查集主要运用与求一些 不相交且有关

    2024年02月13日
    浏览(25)
  • 【算法证明 五】并查集的时间复杂度

    相信如果不是为了刷 leetcode 外,很少有数据结构的数介绍并查集这一数据结构的。并查集的算法模板写起来非常容易,所以刷了并查集相关算法题的人,应该也不会去深入分析这一数据结构,最多知道路径压缩、按秩合并可以做到非常快。深入一点知道 阿克曼函数 α ( n ) 阿

    2024年02月11日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包