📜  连续分数分解算法

📅  最后修改于: 2022-05-13 01:54:59.574000             🧑  作者: Mango

连续分数分解算法

连分数分解法 ( CFRAC ) 是一种适用于整数的通用分解算法。它计算给定整数的因子而不考虑其独特属性。它有一个次指数的运行时间。它于 1931 年由 DH Lehmer 和 RE Powers 首次描述,后来在 1975 年由 Michael A. Morrison 和 John Brillhart 开发成计算机算法。

连分数:
可以表达为以下形式的表达式:

(1)   \begin{equation*} X=a_{0}+\frac{b_{1}}{a_{1}+\frac{b_{2}}{a_{2} \ldots+\frac{b_{n-1}}{a_{n-1}+\frac{b_{n}}{a_{n}}}}} \end{equation*}

被称为连分数,其中 a i和 b i是所有i > = 0的实数或复数。当 b i的所有值 为 1,则称为简单连分数。

简单连分数可以表示为:

(2)   \begin{equation*} \left[a_{0} ; a_{1}, a_{2} \ldots a_{n}\right]=a_{0}+\frac{1}{a_{1}+\frac{1}{a_{2} \ldots+\frac{1}{a_{n-1}+\frac{1}{a_{n}}}}} \end{equation*}

其中 C k = [a 0; a 1 , a 2 , ..., a n ] for k<=n 是简单连分数的第 k 个收敛。
一个无限连分数 [a 0 ; a 1 , a 2 , ..., a k, ...] 被定义为收敛 C k =[a0; a1, a2, ..., 一个]

算法:
该算法使用在 (mn) 1/2的连分数中对某些 m 产生的残差来产生一个平方数。

该算法求解数学方程:

(3)   \begin{equation*} x^{2} \equiv y^{2}(\bmod (n)) \end{equation*}


该方程通过计算 m 的值来求解,使得 m 2 (mod(n)) 具有最小上界。
  • CFRAC 算法的时间复杂度为:

(4)   \begin{equation*} O\left(e^{\sqrt{2 \log n \log \log n}}\right) \end{equation*}

示例 1:

Input: continued_fraction((10/7))
Output: [1, 2, 3]

Explanation:

(5)   \begin{equation*} [1,2,3]=1+\frac{1}{2+\frac{1}{3}}=1+\frac{1}{\frac{7}{3}}=1+\frac{3}{7}=\frac{10}{7} \end{equation*}

示例 2:

Input:  list(continued_fraction_convergents([0, 2, 1, 2]))
Output: [0, 1/2, 1/3, 3/8]
Explanation:

(6)    \begin{equation*} \begin{array}{c} {[0,2,1,2]=0+\frac{1}{2+\frac{1}{1+\frac{1}{2}}}} \\ c_{1}=0, c_{2}=0+\frac{1}{2}=\frac{1}{2} \cdot c_{3}=0+\frac{1}{2+\frac{1}{1}}=\frac{1}{3} \cdot c_{4}=0+\frac{1}{2+\frac{1}{1+\frac{1}{2}}}=0+\frac{1}{2+\frac{1}{3}}=0+\frac{1}{2+\frac{1}{2}}=\frac{1}{\frac{1}{3}}=\frac{3}{8} \end{array} \end{equation*}

示例 3:

Input: continued_fraction_reduce([1, 2, 3, 4, 5]) 
Output: 225/157
Explanation:

(7)    \begin{equation*} 1+\frac{1}{2+\frac{1}{3+\frac{1}{4+\frac{1}{5}}}}=1+\frac{1}{2+\frac{1}{3+\frac{1}{21}}}=1+\frac{1}{2+\frac{1}{3+\frac{5}{5}}}=1+\frac{1}{2+\frac{1}{68}}=1+\frac{1}{2+\frac{21}{68}}=1+\frac{1}{\frac{157}{68}}=1+\frac{68}{157}=\frac{225}{157} \end{equation*}


执行:
代码:将分数转换为连分数表示
#using sympy module
from sympy.ntheory.continued_fraction import continued_fraction
from sympy import sqrt
#calling continued_fraction method
continued_fraction(10/7)

输出:

[1, 2, 3]

代码 2:将连分数转换为分数。

#using sympy module
from sympy.ntheory.continued_fraction import continued_fraction_reduce 
  
#calling continued_fraction_reduce method
continued_fraction_reduce([1, 2, 3, 4, 5])

输出:

225/157

代码 3:从 Continued 分数中获取收敛项列表。

# using sympy module
from sympy.core import Rational, pi
from sympy import S
from sympy.ntheory.continued_fraction import continued_fraction_convergents, continued_fraction_iterator      
# calling continued_fraction_convergents method and 
# passing it as a parameter to a list
list(continued_fraction_convergents([0, 2, 1, 2]))

输出:

[0, 1/2, 1/3, 3/8]