Stern-Brocot 树与 Farey 序列
Stern-Brocot 树¶
Stern-Brocot 树是一种维护分数的优雅的结构。它分别由 Moritz Stern 在 1858 年和 Achille Brocot 在 1861 年发现这个结构。
概述¶
Stern-Borcot 树从两个简单的分数开始:
这个
每次我们在相邻的两个分数
既然我们称它为 Stern-Brocot 树,那么它总得有一个树的样子对吧。来一张图:
你可以把第
性质¶
接下来讨论一下 Stern-Brocot 树的性质。
单调性¶
在每一层的序列中,真分数是单调递增的。
略证:只需要在
就行了。这个很容易,直接做一下代数变换即可
另一边同理可证。
最简性¶
序列中的分数(除了
略证:为证明最简性,我们首先证明对于序列中连续的两个分数
显然,我们只需要在
后半部分同理。证明了这个,利用扩展欧几里德定理,如果上述方程有解,显然
有了上面的证明,我们可以证明
有了这两个性质,你就可以把它当成一棵平衡树来做了。建立和查询就向平衡树一样做就行了。
实现¶
构建实现
1 2 3 4 5 6 7 8 | // C++ Version
void build(int a = 0, int b = 1, int c = 1, int d = 0, int level = 1) {
int x = a + c, y = b + d;
// ... output the current fraction x/y
// at the current level in the tree
build(a, b, x, y, level + 1);
build(x, y, c, d, level + 1);
}
|
1 2 3 4 5 6 7 | # Python Version
def build(a = 1, b = 1, c = 1, d = 0, level = 1):
x = a + c; y = b + d
# ... output the current fraction x/y
# at the current level in the tree
build(a, b, x, y, level + 1)
build(x, y, c, d, level + 1)
|
查询实现
1 2 3 4 5 6 7 8 9 | // C++ Version
string find(int x, int y, int a = 0, int b = 1, int c = 1, int d = 0) {
int m = a + c, n = b + d;
if (x == m && y == n) return "";
if (x * n < y * m)
return 'L' + find(x, y, a, b, m, n);
else
return 'R' + find(x, y, m, n, c, d);
}
|
1 2 3 4 5 6 7 8 9 | # Python Version
def find(x, y, a = 0, b = 1, c = 1, d = 0):
m = a + c; n = b + d
if x == m and y == n:
return ""
if x * n < y * m:
return 'L' + find(x, y, a, b, m, n)
else:
return 'R' + find(x, y, m, n, c, d)
|
Farey 序列¶
Stern-Brocot 树与 Farey 序列有着极其相似的特征。第
显然,上述构建 Stern-Brocot 树的算法同样适用于构建 Farey 序列。因为 Stern-Brocot 树中的数是最简分数,因此在边界条件(分母)稍微修改一下就可以形成构造 Farey 序列的代码。你可以认为 Farey 序列
Farey 序列同样满足最简性和单调性,并且满足一个与 Stern-Brocot 树相似的性质:对于序列中连续的三个数
由 Farey 序列的定义,我们可以得到
最佳有理逼近¶
讨论如何用有理数“最佳地”逼近无理数,不妨假设无理数落入
“最佳”一词的概念:选定的有理数必须保证,比它与无理数的距离更近的有理数,分母都比它大。不存在分母比它小的有理数,到给定无理数的距离更近。
最佳有理数:在 Farey 数列的某一行中,与给定无理数距离最近的那个有理数。
这个有理数可能在下面几行依旧与无理数“距离最近”,但一定有某一行,会找到一个新的有理数,与无理数距离更近。因此去重复后可以得到 最佳逼近有理数列,分母严格递增,距离递减。
比无理数大的称为上逼近,否则为下逼近。由于无理数和有理数之间一定有有理数,最佳逼近有理数列必然为若干个上逼近,之后若干个下逼近,交替进行的形式。
有结论:
渐进分数必然为最佳逼近。偶项渐进分数全都是下逼近,奇项渐进分数全都是上逼近。渐进分数列是下上交错的逼近。
在最佳逼近有理数列中,渐进分数是下上关系改变之前的倒数第一个数。如果将最佳逼近有理数列都写成有限简单连分数,那么在渐进分数之后(下上关系改变之后),连分数长度加一。
例如,
那么它的渐进分数列是:
它的最佳逼近有理数列是:
从每个渐进分数(不包含)开始,到下一个渐进分数(包含)为止,同为上逼近,或同为下逼近。
在最佳逼近列中,每一个最佳分数是上一个最佳分数与再往前一个渐进分数的分子分母对应求和。
Dirichlet 逼近定理¶
Dirichlet 逼近定理是说,对于任意的一个无理数
更强的结论是,在右边的分母上能放一个
更进一步的定理是 Kronecker 的逼近定理。
如果
这两个定理都可以用抽屉原理来解决。事实上,历史上第一次正式提出抽屉原理,就是 Dirichlet 为了解决 Pell 方程 而研究这个有理数逼近条件才正式提出来抽屉原理的。
当然,采用抽屉原理的证明可以发现,上文中提到的最佳逼近有理数列,每项满足定理中右边改成分母为一次式的不等式。
进一步有结论,渐进有理数列中,每一项均满足 Dirichlet 逼近定理的不等式。
本页面主要译自博文 Дерево Штерна-Броко. Ряд Фарея 与其英文翻译版 The Stern-Brocot Tree and Farey Sequences。其中俄文版版权协议为 Public Domain + Leave a Link;英文版版权协议为 CC-BY-SA 4.0。
build本页面最近更新:,更新历史
edit发现错误?想一起完善? 在 GitHub 上编辑此页!
people本页面贡献者:OI-wiki
copyright本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用