1. 法雷数列的来源
约翰·法雷 是英国一位多才多艺的“ 杂家” , 生活在拿破仑时代, 职业是土地丈量员, 却有着广泛的爱好, 喜欢搜集奇异的石头、矿物, 兴致来潮, 撰写小块科普文章在《哲学杂志》上发表, 题材广泛涉及到地质、音乐、钱币、车轮、慧星, 偶尔也涉及数学小品。1816年, 当他审读亨利 戈德温所编的“ 小数商表” 时,忽然有一个问题涌上心头, 既约最简真分数有多少呢能不能把它们按一定的顺序排列出来兴致所及, 急切难忍, 他立即推开戈氏冗繁的“商表” , 动手排列起来, 一遍又一遍, 没有头绪。这时他想到两点:一是真分数有无限多个, 要“ 全部” 排出, 必须限制分母的大小二是可按递增的顺序去排列, 容易发现规律 他终于排出来了, 还发现了若干性质。发表后, 立即被当时数学家们抓住, 后来数学家柯西发现这分数串在数学中很有用,并名之为法雷数列。 没成想早在14年前, 一位名叫哈罗斯的人, 就发现并公布了自己的研究结故。名之哈罗斯一法雷数列。
2. 法雷数列的定义
对任意给定的一个自然数$n$,将分母小于等于$n$的不可约的真分数按升序排列,并且在第一个分数之前加上$\frac{0}{1}$,在最后一个分数之后加上$\frac{1}{1}$,这个序列称为$n$级法雷数列,以$F_n$表示。如$F_6$为:$\frac{0}{1}$,$\frac{1}{6}$,$\frac{1}{5}$,$\frac{1}{4}$,$\frac{1}{3}$,$\frac{2}{5}$,$\frac{1}{2}$,$\frac{3}{5}$,$\frac{2}{3}$,$\frac{3}{4}$,$\frac{4}{5}$,$\frac{5}{6}$,$\frac{1}{1}$。
3. 推导法雷数列方法
以上面的$F_6$为例。对一般的法雷数列中的两个分数$\frac{a}{b}$和$\frac{c}{d}$,可以得到它们中间的那个分数,即$\frac{p}{q}=\frac{a+c}{b+d}$(前提是得出的$q$值小于或者等于给定的$n$值)。所以由$\frac{0}{1}$和$\frac{1}{1}$得出$\frac{1}{2}$,由$\frac{0}{1}$和$\frac{1}{2}$得出$\frac{1}{3}$,由$\frac{1}{2}$和$\frac{1}{1}$得出$\frac{2}{3}$,依次类推……即可得出所有的法雷数列中的分数。
4. 法雷数列的一些性质
性质$1$:$n$级法雷数列中相邻两个分数$\frac{a}{b}$和$\frac{c}{d}$的差为$\frac{1}{bd}$,并且所有的差中最小值为$\frac{1}{n(n-1)}$;
性质$2$:除了$1$级法雷数列外,所有的法雷数列都有奇数个元素,其中居于正中间的那个元素一定是$\frac{1}{2}$;
性质$3$:当$n$趋于正无穷时,$n$级法雷数列包含的元素的个数趋于$\frac{3}{\pi*\pi}*n^2\equiv 0.30396355*n^2$。
5. 用法雷数列逼近一个实数的方法
Step$1$: 置实数$f$的下界为$\frac{a}{b}=\frac{0}{1}$, 上界为$\frac{c}{d}=\frac{1}{1}$。
Step$2$: 计算出下界和上界之间的数$\frac{p}{q}=\frac{a+c}{b+d}$
Step$3$: 若$q>n$(分母大于指定值),计算中止。
若$\frac{p}{q}=f$,$\frac{a}{b}=\frac{p}{q}$ , $\frac{c}{d}=\frac{p}{q}$, 计算中止。
若$\frac{p}{q}<f$, 置下界$\frac{a}{b}=\frac{p}{q}$;
若$\frac{p}{q}>f$, 置上界$\frac{c}{d}=\frac{p}{q}$;
Step$4$, 重复step $2-3$
当计算终止时,$\frac{a}{b}$为这个实数的下界,$\frac{c}{d}$为这个实数的上界。
6. 参考程序
给出一个实数,求出这个实数在$n$级法雷数列下的下界和上界,参考程序如下:
1 #include<iostream> 2 using namespace std; 3 4 int a,b,c,d,p,q; 5 int n; 6 double f; 7 void solve() 8 { 9 a = 0,b = 1,c = 1,d = 1,p = a + c,q = b + d; 10 while(q <= n) 11 { 12 if(f > (double)p/q) 13 { 14 a = p; 15 b = q; 16 } 17 else 18 { 19 c = p; 20 d = q; 21 } 22 p = a + c; 23 q = b + d; 24 } 25 } 26 27 int main() 28 { 29 while(cin>>n>>f) 30 { 31 solve(); 32 cout<<a<<"/"<<b<<" << "<<f<<" << "<<c<<"/"<<d<<endl; 33 } 34 return 0; 35 }