n节点的无序标号树有多少种:拉格朗日反演的应用

摘要: 拉格朗日反演的应用

【对算法,数学,计算机感兴趣的同学,欢迎关注我哈,原创文章】
我的网站:潮汐朝夕的生活实验室
我的公众号:算法题刷刷
我的知乎:潮汐朝夕
我的github:FennelDumplings
我的leetcode:FennelDumplings


各位好,本文我们继续来讨论算法分析的问题。

对于图论中的很多算法,其时间复杂度的分析经常需要基于 n 节点的无序标号树共有多少种这个问题。本文我们就来解决这个问题,顺便看一下拉格朗日反演的应用。

在前面的几篇文章中,我们解决了诸如 N 节点二叉树的种类数,快速排序平均比较次数等算法分析中的最基础的问题。在处理这些问题的过程中,我们认识到生成函数往往是解决问题的核心。

通过生成函数解决问题,可以流程化地分为 3 步:

  1. 导出生成函数 T ( z ) T(z) T(z) 满足的方程。
  2. 求解方程得到 T ( z ) T(z) T(z)
  3. T ( z ) T(z) T(z) 展开,取其中 z N z^{N} zN 的系数。

在文章 二叉树的计数:直接方法与间接方法 中,我们初步了解了符号方法的应用。引入符号方法后,解决第 1 步就变得比较简单。

第 2 步是求解函数方程或微分方程,这是相对比较完善的数学领域,根据具体的方程,去找相应的内容即可。

对于第 3 步也是有一些非常有力的工具的:拉格朗日反演就是其中一个。本文我们就用拉格朗日反演来解决 n 节点无序标号树个数这个经典问题。


问题描述

对于一个 N 节点的图,如果它有 N - 1 条边,并且是连通图,那它就是一棵 N 节点的树。我们的讨论就是在这样的一个结构上展开的。

但是这样的树结构还有很多分类,比如:

  • 有根树还是自由树:自由树就是最一般的无环连通图,给定了这个图,指定不同的节点作为根节点如果视为同一棵树,那么称为无根树或自由树;如果指定哪个节点为根需要考虑,那么称为有根树。
  • 有序树还是无序树:对于有根树来说,根节点连接了若干子树,修改这些子树连接到根的顺序,所形成的新树如果视为不同的树,则称为有序树;否则子树的顺序不重要,称为无序树,这些子树可以视为另外一些无序树的多重集。
  • 标号树还是无标号树:树的节点是否可区分,如果不可区分,称为无标号树;否则节点就有不同标识,称为有标号树。

因此当我们讨论树的问题的时候,首先要明确我们讨论的是什么树。这里我们讨论的是标号有根无序树,也称为 Cayley 树。因为 19 世纪凯莱对该问题做过研究,其结论称为凯莱公式:

凯莱(Cayley)公式

给定 n 个不同的点,组成的无根树的个数为 n n − 2 n^{n-2} nn2

n n − 2 n^{n-2} nn2 给出的是标记无根无序树的计数,由于有根树的计数就是在无根树的计数的基础上,需要从 n n n 个节点中取一个作为根,有 n n n 种不同的取法,因此记 C n C_{n} Cn n n n 个节点的标记有根无序树,有 C n = n n − 1 C_{n} = n^{n-1} Cn=nn1,这与上述凯莱公式是一回事。

凯莱公式的证明方法很多,并且有些证法的背后是非常有用的工具,比如矩阵树定理、比如 Prufer 编码,这方面内容可以参考图论相关的书。本文我们看一下基于拉格朗日反演的推导过程。

指数生成函数 C ( z ) C(z) C(z) 的函数方程

C \mathcal{C} C 为所有可能的 Cayley 树的集合。其中具有 N N N 个节点的 Cayley 树的个数记为 C N C_{N} CN,其指数生成函数为:

C ( z ) = ∑ N = 0 ∞ C N z N N ! = ∑ ∣ c ∣ ∈ C z ∣ c ∣ ∣ c ∣ ! C(z) = \sum\limits_{N=0}\limits^{\infty}C_{N}\frac{z^{N}}{N!} = \sum\limits_{|c|\in\mathcal{C}}\frac{z^{|c|}}{|c|!} C(z)=N=0CNN!zN=cCc!zc

C ( z ) C(z) C(z) 所满足的函数方程的推导过程,用到了使用生成函数对组合对象计数的符号方法,其推导过程涉及到一些抽象概念的定义以及相关的定理。

这里我们直接用结果: C ( z ) = z e C ( z ) C(z) = ze^{C(z)} C(z)=zeC(z)。在以后详细介绍符号方法时,我们再回到这里,将上式的推导过程补上。

拉格朗日反演定理

拉格朗日反演定理

如果生成函数 A ( z ) = ∑ n = 0 ∞ a n z n A(z) = \sum\limits_{n=0}\limits^{\infty}a_{n}z^{n} A(z)=n=0anzn 满足函数方程 z = f ( A ( z ) ) z = f(A(z)) z=f(A(z)),其中 f ( z ) f(z) f(z) 满足 f ( 0 ) = 0 f(0) = 0 f(0)=0,且 f ′ ( 0 ) ≠ 0 f'(0) \neq 0 f(0)=0,则:
a n = [ z n ] A ( z ) = 1 n [ u n − 1 ] ( u f ( u ) ) n a_{n} = [z^{n}]A(z) = \frac{1}{n}[u^{n-1}](\frac{u}{f(u)})^{n} an=[zn]A(z)=n1[un1](f(u)u)n
以及:
[ z n ] ( A ( z ) ) m = m n [ u n − m ] ( u f ( u ) ) n [z^{n}](A(z))^{m} = \frac{m}{n}[u^{n-m}](\frac{u}{f(u)})^{n} [zn](A(z))m=nm[unm](f(u)u)n
并且:
[ z n ] g ( A ( z ) ) = 1 n [ u n − 1 ] g ′ ( u ) ( u f ( u ) ) n [z^{n}]g(A(z)) = \frac{1}{n}[u^{n-1}]g'(u)(\frac{u}{f(u)})^{n} [zn]g(A(z))=n1[un1]g(u)(f(u)u)n

以上定理的可以追溯到 18 世纪,其证明可以参考组合数学方面的书,例如《分析组合学》。

拉格朗日反演对于幂级数的转换,是非常有力的办法。它最大的特点是在函数的逆函数的系数函数的幂之间,提供了直接对应关系。对于一些难解的隐函数,可以考虑用拉格朗日反演来提取系数。


再看二叉树计数的例子

在文章 二叉树的计数:直接方法与间接方法 中我们讨论过二叉树的计数,我们知道具有 N 个节点的二叉树的函数方程如下:

T ( z ) = 1 + z T 2 ( z ) T(z) = 1 + zT^{2}(z) T(z)=1+zT2(z)

在那篇文章中,我们首先通过二次方程求根公式求解出了 T ( z ) T(z) T(z),然后再基于广义二项式定理将结果展开, T n = [ z n ] T ( z ) = 1 n + 1 ( 2 n n ) T_{n} = [z^{n}]T(z) = \frac{1}{n+1}\binom{2n}{n} Tn=[zn]T(z)=n+11(n2n) 给出了具有 N 个节点的二叉树的个数。

而由于原方程可以写为 z T ( z ) = z + ( z T ( z ) ) 2 zT(z) = z + (zT(z))^{2} zT(z)=z+(zT(z))2,记 G ( z ) = z T ( z ) G(z) = zT(z) G(z)=zT(z),有 z = G ( z ) − G 2 ( z ) z = G(z) - G^{2}(z) z=G(z)G2(z),这刚好是拉格朗日反演定理的形式,因此可以取 f ( u ) = u − u 2 f(u) = u - u^{2} f(u)=uu2,根据拉格朗日反演,有:

[ z n ] G ( z ) = 1 u [ u n − 1 ] ( n u − u 2 ) n = 1 n [ u n − 1 ] ( 1 1 − u ) n [z^{n}]G(z) = \frac{1}{u}[u^{n-1}](\frac{n}{u-u^{2}})^{n} = \frac{1}{n}[u^{n-1}](\frac{1}{1-u})^{n} [zn]G(z)=u1[un1](uu2n)n=n1[un1](1u1)n

参考 生成函数的性质速查 中的速查表,可得 u n − 1 ( 1 − u ) n = ∑ k = n − 1 ∞ ( k n − 1 ) u k \frac{u^{n-1}}{(1-u)^{n}} = \sum\limits_{k=n-1}\limits^{\infty}\binom{k}{n-1}u^{k} (1u)nun1=k=n1(n1k)uk。因此:

[ u n − 1 ] 1 ( 1 − u ) n = [ u 2 n − 2 ] u n − 1 ( 1 − u ) n = ( 2 n − 2 n − 1 ) [u^{n-1}]\frac{1}{(1-u)^{n}} = [u^{2n-2}]\frac{u^{n-1}}{(1-u)^{n}} = \binom{2n-2}{n-1} [un1](1u)n1=[u2n2](1u)nun1=(n12n2)

因此:

[ z n ] G ( z ) = 1 n ( 2 n − 2 n − 1 ) [z^{n}]G(z) = \frac{1}{n}\binom{2n-2}{n-1} [zn]G(z)=n1(n12n2)

代回 T ( z ) T(z) T(z) 有:

[ z n ] T ( z ) = [ z n + 1 ] G ( z ) = 1 n + 1 ( 2 n n ) [z^{n}]T(z) = [z^{n+1}]G(z) = \frac{1}{n+1}\binom{2n}{n} [zn]T(z)=[zn+1]G(z)=n+11(n2n)

这与我们之前通过直接解方程然后再进行展开得到的结果一样。不同的是我们通过拉格朗日反演,将 [ z n ] T ( z ) [z^{n}]T(z) [zn]T(z) 的问题转化为了 [ u n − 1 ] 1 ( 1 − u ) n [u^{n-1}]\frac{1}{(1-u)^{n}} [un1](1u)n1 的问题,而后者可以通过查表直接得到。

从这个例子可以看出拉格朗日反演的价值,可以将难求展开式系数的函数 T ( z ) T(z) T(z) 转化为好求展开式系数的函数,对于本例,该函数是 1 ( 1 − u ) n \frac{1}{(1-u)^{n}} (1u)n1

C n C_{n} Cn 的解

由于 C ( z ) = z e C ( z ) C(z) = ze^{C(z)} C(z)=zeC(z),可以写为 z = C ( z ) e − C ( z ) z = C(z)e^{-C(z)} z=C(z)eC(z),这是满足拉格朗日定理的形式,于是可以取 f ( u ) = u e − u f(u) = ue^{-u} f(u)=ueu,于是立即可以得到:

[ z n ] C ( z ) = 1 n [ u n − 1 ] e u n = 1 n n n − 1 ( n − 1 ) ! = n n − 1 n ! [z^{n}]C(z) = \frac{1}{n}[u^{n-1}]e^{un} = \frac{1}{n}\frac{n^{n-1}}{(n-1)!} = \frac{n^{n-1}}{n!} [zn]C(z)=n1[un1]eun=n1(n1)!nn1=n!nn1

于是得到凯莱公式:

C n = n ! [ z n ] C ( z ) = n n − 1 C_{n} = n![z^{n}]C(z) = n^{n-1} Cn=n![zn]C(z)=nn1

这里也看出了拉格朗日反演的作用,将满足方程 C ( z ) = z e C ( z ) C(z) = ze^{C(z)} C(z)=zeC(z) 的函数 C ( z ) C(z) C(z) 的展开式系数的问题,转化为了 e u n e^{un} eun 的展开式系数的问题,而 e u n e^{un} eun 的展开式系数是好求的,于是我们甚至没有解方程,就轻易得到了 C ( z ) C(z) C(z) 的展开式系数。

总结

本文我们讨论了图论中的算法分析的常见问题:n 节点的无序标号树共有多少个。其结果称为凯莱公式。

本文的推导基于拉格朗日反演,首先介绍了拉格朗日反演定理的描述,然后用该定理重新解决了二叉树计数的问题,可以发现拉格朗日反演在简化生成函数计数问题的价值。

凯莱公式是图论中的经典结论,主流的推导方式有矩阵树定理和 Prufer 编码等,前置的知识都比较冗长。而本文使用拉格朗日反演,非常轻易地就得到了结果。

当然为了突出重点,一些结论本文跳过了推导步骤,比如 n 节点无序标号树的指数生成函数满足的函数方程 C ( z ) = z e C ( z ) C(z) = ze^{C(z)} C(z)=zeC(z) 是怎么推导出来的;比如拉格朗日反演定理是怎么推导出来的。后续我们再探讨这些问题。

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

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

相关文章

【leetcode】100. 相同的树

题目链接 100. 相同的树 bool isSameTree(struct TreeNode* p, struct TreeNode* q) {if (p && q) {return p->val q->val // 分解&& isSameTree(p->left, q->left)&& isSameTree(p->right, q->right);} else if (p NULL &&…

Linux第50步_移植ST公司的linux内核第2步_编译ST公司的linux源码和修改网络驱动

1、修改“linux-5.4.31”目录下的“Makefile” 1)、使用VSCode打开“linux-5.4.31.code-workspace” 2)、点击“linux-5.4.31”目录下的“Makefile” 3)、点击“编辑”,点击“查找”,输入“CROSS_COMPILE回车”,找到“ARCH ? $(SUBARCH)”…

回归预测模型:MATLAB岭回归和Lasso回归

1. 岭回归和Lasso回归的基本原理 1.1 岭回归: 岭回归(Ridge Regression) 是一种用于共线性数据分析的技术。共线性指的是自变量之间存在高度相关关系。岭回归通过在损失函数中添加一个L2正则项( λ ∑ j 1 n β j 2 \lambda \s…

JavaWeb:关于登录认证的简单拓展

前提介绍 本文基于文章-------JavaWeb:SpringBootWeb登录认证 --黑马笔记 -------再做简单拓展 如果没有关于登录认证知识的基础,可以先看上面所说的的文章,文章在专栏javaweb中,下面我为了大家观看,直接放了链接。…

2024年华为OD机试真题-堆内存申请-Python-OD统一考试(C卷)

题目描述: 有一个总空间为100字节的堆,现要从中新申请一块内存,内存分配原则为优先紧接着前一块已使用内存分配空间足够且最接近申请大小的空闲内存。 输入描述: 输入: 第1行是1个整数,表示期望申请的内存字节数; 第2到N行是用空格分割的两个整数,表示当前已分配的内存…

26. 可变参数和Collection集合工具类

可变参数与Collections 1. 可变参数1. 概述2. 格式3. 代码示例4. 注意事项 2. Collections集合工具类2.1 概述2.2 方法2.3 代码示例2.4 注意事项 1. 可变参数 1. 概述 可变参数(Variable Arguments)是指在参数列表中允许传入不定个数的参数。在许多编程…

《动手学深度学习(PyTorch版)》笔记7.6

注:书中对代码的讲解并不详细,本文对很多细节做了详细注释。另外,书上的源代码是在Jupyter Notebook上运行的,较为分散,本文将代码集中起来,并加以完善,全部用vscode在python 3.9.18下测试通过&…

如何在CentOS7上使用防火墙保护Docker容器的端口

防火墙设置对Docker容器内开放的端口无效? 在主机或虚机上运行Docker容器时,即便主机启用了firewalld服务,仍然存在一些安全隐患,尤其是当Docker容器内打开端口并监听0.0.0.0时,存在即使通过firewall-cmd配置了阻止某…

前端主流框架:项目运行命令 npm 详解

作为一位资深前端开发,我对npm(Node Package Manager)的使用有着深入的了解。npm是Node.js的包管理器,用于安装、管理和删除各种前端库和工具。现在,让我们深入了解npm在Vue、React、Angular和Vue 3项目中的一些基本使…

【软件工程导论】实验二——编制数据字典(数字化校园系统案例分析)

数字化校园系统案例分析 问题定义实验内容编制内容1数据项数据流处理逻辑数据存储 2外部实体 问题定义 数字化校园系统期望以数字化信息和网络为基础,在计算机和网络技术上建立起对教学、科研、管理、技术服务、生活服务等校园信息的收集、处理、整合、存储、传输和…

嵌入式Qt 第一个Qt项目

一.创建Qt项目 打开Qt Creator 界面选择 New Project或者选择菜单栏 【文件】-【新建文件或项目】菜单项 弹出New Project对话框,选择Qt Widgets Application 选择【Choose】按钮,弹出如下对话框 设置项目名称和路径,按照向导进行下一步 选…

EMC学习笔记(二十六)降低EMI的PCB设计指南(六)

降低EMI的PCB设计指南(六) 1.PCB布局1.1 带键盘和显示器的前置面板PCB在汽车和消费类应用中的应用1.2 敏感元器件的布局1.3 自动布线器 2.屏蔽2.1 工作原理2.2 屏蔽接地2.3 电缆屏蔽至旁路2.4 缝隙天线:冷却槽和缝隙 tips:资料主要…

MySQL篇----第二十一篇

系列文章目录 文章目录 系列文章目录前言一、什么是乐观锁二、什么是悲观锁三、什么是时间戳四、什么是行级锁前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 一、…

无人机概述及系统组成,无人机系统的构成

无人机的定义 无人驾驶航空器,是一架由遥控站管理(包括远程操纵或自主飞行)的航空器,也称遥控驾驶航空器,以下简称无人机。 无人机系统的定义 无人机系统,也称无人驾驶航空器系统,是指一架无人…

屏幕字体种类介绍

[ Script and font support in Windows ] [Windows 中的脚本和字体支持] 在Windows 2000 以前,Windows 的每个主要版本都会添加对新脚本的文本显示支持。本文介绍了每个主要版本中的更改。 Since before Windows 2000, text-display support for new scr…

树莓派4B(Raspberry Pi 4B)使用docker搭建springBoot/springCloud服务

树莓派4B(Raspberry Pi 4B)使用docker搭建springBoot/springCloud服务 前提:本文基于Ubuntu,Java8,SpringBoot 2.6.13讲解 准备工作 准备SpringBoot/SpringCloud项目jar包 用 maven 打包springBoot/springCloud项目&…

idea中vue文件如何快捷打出html标签结构,不写<

例如写一个<button></button>标签&#xff1a;快捷键如下 先写一个button&#xff0c;然后再按tab键即可自动生成一对标签。 演示&#xff1a; 步骤一&#xff1a; 步骤二&#xff1a;

PHP中读取(截取substr)字符串前N个字符或者从第几个字符开始取几个字符

html <?php $str "123456789";echo substr($str , 0 , 3);//从左边第一位字符起截取3位字符&#xff1a;结果&#xff1a;123echo substr($str , 3 , 3);//从左边第3位字符起截取3位字符&#xff1a;结果&#xff1a;456?> html <?php$rest substr(&…

【华为OD机试】 最长子字符串的长度(一)【2024 C卷|100分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 给你一个字符串 s,首尾相连成一个环形,请你在环中找出 o 字符出现了偶数次最长子字符串的长度。 输入描述 输入是一个小写字母组成的字符串 输出描述 输出是一个整数 备注 1 ≤ s.length…