Python 探讨斐波拉契数列模素数的周期问题


前言

定义    \; 斐波拉契数列又称黄金分割数列,是指数列 1、1、2、3、5、8、13、21、34、55 …,通过递推的方式可准确定义为 F 0 = 0 ,    F 1 = 1 ,    F n = F n − 1 + F n − 2 ,    ( n ≥ 2 , n ∈ N ∗ ) F_0=0, \; F_1=1, \; F_n=F_{n-1}+F_{n-2}, \; (n \geq 2, n ∈ N^*) F0=0,F1=1,Fn=Fn1+Fn2,(n2,nN)

ω = 1 + 5 2 \omega =\frac{1+\sqrt{5}}{2} ω=21+5 ω ˉ = 1 − 5 2 \bar{\omega} =\frac{1-\sqrt{5}}{2} ωˉ=215 ,则有斐波拉契数列的通项公式: F n = 1 5 ( ω n + ω ˉ n ) F_n = \frac{1}{\sqrt{5}} \left( \omega^n + \bar{\omega}^n \right) Fn=5 1(ωn+ωˉn)

性质    \; 斐波拉契数列前一项与后一项之比的极限为黄金分割比,即有 lim ⁡ n → + ∞ F n F n + 1 = 5 − 1 2 \lim_{n \to +\infty} \frac{F_n}{F_{n+1}} = \frac{\sqrt{5}-1}{2} n+limFn+1Fn=25 1


一、生成斐波拉契数列

按照递推公式即可写出如下代码:

def fibonacci(n):
    a, b = 0, 1
    for i in range(n):
        a, b = b, a + b
        yield a

使用 list(fibonacci(10)) 便输出 [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] 。

二、创建素数列表

此步方法比较多,大家可以自己发挥,最后使用 primes(20) 要能输出小于 20 20 20 的全体素数 [2, 3, 5, 7, 11, 13, 17, 19] 。本文中至少要求我们能快速生成 10000 10000 10000 以内的素数即可,这是容易实现的,代码不再展示。

三、搜索周期数列的循环节

3.1 斐波拉契数列模 p p p 的周期

关于一般周期数列循环节的讨论,原本是比较麻烦的,但由于斐波拉契数列模素数 p p p 的周期很有规律,因此可以简单进行编程处理。

首先解释一下循环节的含义,循环节是指周期数列里一个最小正周期里的子数列。比如周期数列 [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, …] 里的循环节为 [1, 2, 3] 。

周期数列的周期往往是指该数列循环节的长度,比如上面的周期数列,其周期为 3 3 3

斐波拉契数列模素数 p p p 之后形成的新的数列是一个周期数列,我们对于该周期数列的循环节和周期都是十分感兴趣的。

在此,我们给出一个重要结论:

定理    \; { F n } \{ F_n \} {Fn} 为斐波拉契数列, p p p 为大于 5 5 5 的素数,数列 F \mathscr{F} F 为斐波拉契数列 { F n } \{ F_n \} {Fn} 模素数 p p p 后的新数列,则当 p = 1 , 4 m o d    5 p = 1, 4 \mod 5 p=1,4mod5 时, F \mathscr{F} F 的周期为 p − 1 p-1 p1 p − 1 p-1 p1 的因子;当 p = 2 , 3 m o d    5 p = 2, 3 \mod 5 p=2,3mod5 时, F \mathscr{F} F 的周期为 2 p + 2 2p+2 2p+2 2 p + 2 2p+2 2p+2 的因子。

上述定理的证明详见论文 The Period of the Fibonacci Sequence Modulo j 中的定理5定理6

上述定理告述我们,斐波拉契数列模 p p p 的周期最多为 2 p + 2 2p+2 2p+2 。因此对于模 10000 10000 10000 以内的素数,最大的一个素数为 9973 9973 9973,其周期最多为 19948 19948 19948 。算法仅要求两个周期的匹配即可,故需要至少前 19948 ⋅ 2 = 39896 19948 \cdot 2 = 39896 199482=39896 个斐波拉契数。本文我们取前 40000 40000 40000 个斐波拉契数,让他们皆模 p p p 产生周期数列 F \mathscr{F} F

3.2 循环节的搜寻代码

我们按照上述要求,编写循环节搜寻的 Python 代码:

lstt = [7,1,4,2,8,5,0,7,1,4,2,8,5,0,7,1,4,2]
t = len(lstt)//2
s = 0

for k in range(2, t+1):
    if lstt[0:k]==lstt[k:2*k]:
        print(lstt[0:k])
        print(f'循环节长度为:{len(lstt[0:k])}')
        print(f'不同元素个数为:{len(set(lstt[0:k]))}', '\n')
        s +=1
        break

输出结果如下:

[7, 1, 4, 2, 8, 5, 0]
循环节长度为:7
不同元素个数为:7 

3.3 完整实现斐波拉契数列模 p p p 循环节

a = primes(10000)
b = list(fibonacci(40000))

s = 0
u = 0
r = 0
lst_1 = []
lst_2 = []

for i in a:
    lst = []
    for j in b:
        lst.append(j % i)
    # 计算数列中的循环节
    t = len(lst)//2
    for k in range(2, t+1):
        if lst[0:k]==lst[k:2*k]:
            print(lst[0:k])
            print(f'循环节长度为:{len(lst[0:k])}')
            print(f'p={i} 时循环节的不同元素个数为:{len(set(lst[0:k]))}')
            if len(lst[0:k])==2*i+2:
                print(f'最小正周期等于 2p+2', '\n')
                lst_1.append(i)
                u +=1
            elif len(lst[0:k])==i-1:
                print(f'最小正周期等于 p-1', '\n')
                lst_2.append(i)
                r +=1
            else:
                print('\n')
            s +=1
            break

print(f'一共有 {s} 个循环节被输出')
print(f'一共有 {len(a)} 个素数被讨论') 
print(f'一共有 {u} 个模数 p 满足最小正周期等于 2p+2')
print(f'满足最小正周期等于 2p+2 的 p 为:{lst_1}')
print(f'一共有 {r} 个模数 p 满足最小正周期等于 p-1')
print(f'满足最小正周期等于 p-1 的 p 为:{lst_2}')
print(f'满足最小正周期等于 2p+2 或 p-1 的占比为:{(u+r)/s}')

我们只挑部分输出如下:

一共有 1229 个素数被讨论
一共有 487 个模数 p 满足最小正周期等于 2p+2
一共有 322 个模数 p 满足最小正周期等于 p-1
满足最小正周期等于 2p+2 或 p-1 的占比为:0.6582587469487388

上述结果表明,还有 420 420 420 个模数 p p p 满足周期既不等于 p − 1 p-1 p1 又不等于 2 p + 2 2p+2 2p+2 ,而是它们的某个真因子。

在所有模数里面, p = 9349 p=9349 p=9349 是最特殊的一个了,这时斐波拉契数列模 9349 9349 9349 的周期数列的循环节为

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 1597, 8362, 610, 8972, 233, 9205, 89, 9294, 34, 9328, 13, 9341, 5, 9346, 2, 9348, 1, 0] ,

周期仅为 38 38 38 ,在上述周期里只有 28 28 28 个不同的元素,这是令人十分吃惊的!可以说, 9349 9349 9349 10000 10000 10000 以内,斐波拉契数列的幸运数字


四、面向未来的问题

现在我们在此总结出如下五个问题:

问题1    \; 若将范围扩大到模 1 , 000 , 000 1,000,000 1,000,000 以内的素数,那么一共有多少个模数 p p p 满足周期等于 2 p + 2 2p+2 2p+2 ?又有多少个模数 p p p 满足周期等于 p − 1 p-1 p1 ?此时满足周期等于 2 p + 2 2p+2 2p+2 p − 1 p-1 p1 的占比为多少 ?

问题2    \; 若再将范围扩大到模 100 , 000 , 000 100,000,000 100,000,000 以内的素数,那么一共有多少个模数 p p p 满足周期等于 2 p + 2 2p+2 2p+2 ?又有多少个模数 p p p 满足周期等于 p − 1 p-1 p1 ?此时满足周期等于 2 p + 2 2p+2 2p+2 p − 1 p-1 p1 的占比为多少 ?

问题3    \; 考虑模小于 N N N 的一切素数,记 C 1 ( N ) C_1(N) C1(N) 为满足斐波拉契数列模 p p p 的周期等于 2 p + 2 2p+2 2p+2 的素数 p p p 的个数, C 2 ( N ) C_2(N) C2(N) 为满足模 p p p 的周期等于 p − 1 p-1 p1 的素数 p p p 的个数,则下述极限是否存在 ?若存在,又为何值 ? lim ⁡ N → + ∞ C 1 ( N ) + C 2 ( N ) π ( N ) \lim_{N \to +\infty} \frac{C_1(N)+C_2(N)}{\pi(N)} N+limπ(N)C1(N)+C2(N) 其中 π ( N ) \pi(N) π(N) 表示小于 N N N 的素数个数。

问题4    \; 当范围扩大到模 1 , 000 , 000 1,000,000 1,000,000 以内的素数时,对应斐波拉契数列的幸运数字是多少 ?如果范围进一步扩大到 100 , 000 , 000 100,000,000 100,000,000 时,对应斐波拉契数列的幸运数字又是多少 ?

问题5    \; 如果范围最后扩大到模全体素数时,是否存在斐波拉契数列的幸运数字 ?若存在,该是什么样的素数呢 ?

以上问题 1、2、4 只需要计算机来完成,问题 3、5 需要严格的数学论证。如果你对计算机感兴趣,那么就去完成问题 1、2、4 ;如果你对数论感兴趣,那么就去尝试完成问题 3、5 吧 !

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tengfei Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值