Este algoritmo de fatoração foi desenvolvido por Pierre de Fermat. O algoritmo é baseado na representação do números inteiros ímpares como a diferença de dois quadrados.
$N = a^{2} - b^{2}$
Essa diferença pode ser fatorada da seguinte maneira:
$a^{2} - b^{2} = (a+b)(a-b)$
Se N = cd é uma fatoração de N então
$N = a^{2} - b^{2}$
$c = a+b$
$d = a-b$
$c+d = 2a$
$a = \frac{c+d}{2}$
$c-d = 2b$
$b = \frac{c-d}{2}$
$N = (\frac{c+d}{2})^2 - (\frac{c-d}{2})^2$
Como a = $\sqrt{N + b^2}$,logo a >= $\sqrt{N}$ e a < N.
A idéia do algorimor é percorrer todos os valores de a = |$\sqrt{N}$|...N. Para cada valor de a, verifique se b = $\sqrt{a^2 - N}$ é inteiro e se (a+b) (a-b) são fatores não triviais de N.
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <map> using namespace std; int eh_quadrado(int x){ int y = (int)(sqrt(x+0.5)); return y*y == x; }
int fermat_factor(int N){ int a,b,b2,c,d; for(a=(int)ceil(sqrt(N));a<=N;a++){ b2 = a*a - N; if( eh_quadrado(b2) ){ b = (int)sqrt(b2); c = a+b; if(c!=1 and c!=N) return c; } } } int primo(int n){ if(n==1) return 1; else if( n< 4) return 1; else if( n%2 ==0) return 0; else if( n< 9) return 1; else if( n%3 ==0) return 0; else { int r = (int)sqrt(n); int f = 5; while( f<=r){ if(n%f==0) return 0; if(n%(f+2)==0) return 0; f=f+6; } } return 1; } void factorization(int N, map <int, int> & fatores ){ int f; if(primo(N)){ fatores[N]++; }else{ f = fermat_factor(N); factorization(f, fatores); factorization(N/f, fatores); } } void fermat_factorization(int N, map <int, int> & fatores){ while(N%2==0) { fatores[2]++; N=N/2;} factorization(N, fatores); } void trial_factorization(int N, map <int, int> & fatores){ int i = 3; int limite; while(N%2==0) { fatores[2]++; N=N/2;} limite = (int)sqrt(N); while( N!=1 && i <= limite ){ while(N%i==0) { fatores[i]++; N=N/i;} limite = (int)sqrt(N); i = i+2; } if(N!=1){ fatores[N]++;} } int main(){ /* for(int i=1;i<=10000;i++) if(eh_quadrado(i)) printf("%d\n",i); */ map <int, int> fatores; map <int, int>::iterator iter; printf("fatores:\n"); fermat_factorization(675734124, fatores); printf("%d\n", fatores.size()); for(iter = fatores.begin(); iter!= fatores.end(); iter++){ printf("%d %d\n", iter->first , iter->second); } fatores.clear(); trial_factorization(675734124, fatores); printf("fatores:\n"); printf("%d\n", fatores.size()); for(iter = fatores.begin(); iter!= fatores.end(); iter++){ printf("%d %d\n", iter->first , iter->second); } return 0; }
Saída:
fatores:
5
2 2
3 1
13 1
113 1
38333 1
fatores:
5
2 2
3 1
13 1
113 1
38333 1
fatores:
5
2 2
3 1
13 1
113 1
38333 1
fatores:
5
2 2
3 1
13 1
113 1
38333 1
Nenhum comentário:
Postar um comentário