Dixon的因式分解方法是一种整数因式分解算法。在本文中,解释了此方法以查找复合数的因素。
Dixon因子分解基于数论的众所周知的事实,即:
- 如果和 gcd(x – y,n)可能是n的因子。
例如:
if N = 84923,
by starting at 292, the first number greater than √N and counting up
5052 mod 84923 = 256 = 162
So (505 – 16)(505 + 16) = 0 mod 84923.
Computing the greatest common divisor of 505 – 16 and N using Euclid’s algorithm gives 163, which is a factor of N.
Dixon的因式分解算法:
- 步骤1:选择一个边界B,并确定所有小于或等于B的素数的因数基数(P)。
- 步骤2:搜索正整数z ,这样是B-Smooth。
(1)
B平滑:如果一个正整数的主因子都不大于B,则称其为B平滑。
例如:720 has prime factorization as 24 * 32 * 51
Therefore 720 is 5 smooth because none of its prime factors is greater than 5. - 步骤3:在产生了足够多的这些关系(通常比P的大小小得多)之后,我们使用线性代数方法(例如,高斯消去)将这些关系相乘。重复此步骤,直到我们形成足够数量的平滑正方形为止。
- 步骤4:将所有这些关系相乘后,我们得到最终方程式:
a2 = b2 mod(N)
- 步骤5:因此,上式的因子可以确定为:
GCD(a - b, N), GCD(a + b, N)
Dixon的因式分解算法的分步执行:
- 假设,我们要使用边界B = 7来分解N =23449。因此,分解基数P = {2,3,5,7}。
- 在这里,x = ceil(sqrt(n))=154。因此,我们随机搜索154和N之间的整数,其平方为B平滑。
- 如前所述,如果一个正整数的所有素数均不大于B,则称其为B-平滑。因此,我们发现两个数字分别为970和8621,使得它们的平方都不具有大于7的素数。 。
- 从这里开始,我们得到的第一个相关平方是:
- 970 2 %23499 = 2940 = 2 2 * 3 * 5 * 7 2
- 8621 2 %23499 = 11760 = 2 4 * 3 * 5 * 7 2
- 因此,(970 * 8621) 2 =(2 3 * 3 * 5 * 7 2 ) 2 %23499。即:
14256 2 = 5880 2 %23499。 - 现在,我们发现:
gcd(14256 - 5880, 23449) = 131 gcd(14256 + 5880, 23449) = 179
- 因此,这些因素是:
N = 131 * 179
下面是上述方法的实现:
C++
// C++ implementation of Dixon factorization algo
#include
using namespace std;
#include
// Function to find the factors of a number
// using the Dixon Factorization Algorithm
void factor(int n)
{
// Factor base for the given number
int base[4] = {2, 3, 5, 7};
// Starting from the ceil of the root
// of the given number N
int start = int(sqrt(n));
// Storing the related squares
vector >pairs;
// For every number from the square root
// Till N
int len=sizeof(base)/sizeof(base[0]);
for(int i = start; i < n; i++)
{
vector v;
// Finding the related squares
for(int j = 0; j < len; j++)
{
int lhs = ((int)pow(i,2))% n;
int rhs = ((int)pow(base[j],2)) % n;
// If the two numbers are the
// related squares, then append
// them to the array
if(lhs == rhs)
{
v.push_back(i);
v.push_back(base[j]);
pairs.push_back(v);
}
}
}
vectornewvec;
// For every pair in the array, compute the
// GCD such that
len = pairs.size();
for (int i = 0; i < len;i++){
int factor = __gcd(pairs[i][0] - pairs[i][1], n);
// If we find a factor other than 1, then
// appending it to the final factor array
if(factor != 1)
newvec.push_back(factor);
}
sets;
for (int i = 0; i < newvec.size(); i++)
s.insert(newvec[i]);
for(auto i = s.begin(); i != s.end(); i++)
cout<<(*i)<<" ";
}
// Driver Code
int main()
{
factor(23449);
}
// This code is contributed by chitranayal
Python3
# Python 3 implementation of Dixon factorization algo
from math import sqrt, gcd
import numpy as np
# Function to find the factors of a number
# using the Dixon Factorization Algorithm
def factor(n):
# Factor base for the given number
base = [2, 3, 5, 7]
# Starting from the ceil of the root
# of the given number N
start = int(sqrt(n))
# Storing the related squares
pairs = []
# For every number from the square root
# Till N
for i in range(start, n):
# Finding the related squares
for j in range(len(base)):
lhs = i**2 % n
rhs = base[j]**2 % n
# If the two numbers are the
# related squares, then append
# them to the array
if(lhs == rhs):
pairs.append([i, base[j]])
new = []
# For every pair in the array, compute the
# GCD such that
for i in range(len(pairs)):
factor = gcd(pairs[i][0] - pairs[i][1], n)
# If we find a factor other than 1, then
# appending it to the final factor array
if(factor != 1):
new.append(factor)
x = np.array(new)
# Returning the unique factors in the array
return(np.unique(x))
# Driver Code
if __name__ == "__main__":
print(factor(23449))
输出:
[131 179]