随机算法--Las Vegas--大数因子分解--Pollard Rho启发式算法(c++版)
程序员文章站
2024-01-11 09:57:34
...
随机算法里的大数因子分解(Pollard Rho启发式算法),vc++6.0中实现,写的时候测的数比较小,只用了int,懒得改了,再用的时候再改成更大的数据类型:
001 #include<iostream> 002 #include<vector> 003 #include<algorithm> 004 #include<cmath> 005 #include<stdlib.h> 006 007 using namespace std; 008 009 int randint(int l,int u) 010 { 011 return l+rand()%(u-l+1); 012 } 013 014 int gcd(int m,int n) 015 { 016 return n?gcd(n,m%n):m; 017 } 018 019 bool isPrime(int n) 020 { 021 if(n<2) 022 return true; 023 for(int i=2;i<=pow(n,0.5);i++) 024 if(n%i==0) 025 return false; 026 return true; 027 } 028 029 //判断分解是否结束:0,恰好结束 030 // 1,超过被分解数 031 // 2,分解数不够 032 int ifenough(int n,vector<int>f) 033 { 034 int m=1; 035 for(int i=0;i<f.size();i++) 036 { 037 m*=f[i]; 038 } 039 if(m==n) 040 return 0; 041 if(m>n) 042 return 1; 043 return 2; 044 } 045 void PollardRho(int num,int n,vector<int>& f ) 046 { 047 048 if(isPrime(n)) 049 { 050 f.push_back(n); 051 return; 052 } 053 054 vector<int> x; 055 int i=1; 056 x.push_back(-1); 057 x.push_back(randint(1,n)); 058 059 int y=x[1]; 060 int k=2; 061 while(true) 062 { 063 i++; 064 x.push_back((abs(x[i-1]*x[i-1]-1))%n); 065 066 int d=gcd(abs(y-x[i]),n); 067 068 if(d>1&&d<n) 069 { 070 PollardRho(num,d,f); 071 PollardRho(num,n/d,f); 072 } 073 074 if(i==k) 075 { 076 y=x[i]; 077 k=2*k; 078 } 079 080 if(find(x.begin(),x.end()-1,x[i])!=x.end()-1||ifenough(num,f)==0||ifenough(num,f)==1) 081 { 082 break; 083 } 084 } 085 } 086 087 void repeatRho(int n) 088 { 089 vector<int> f; 090 for(int i=0;i<10000;i++) 091 { 092 f.clear(); 093 PollardRho(n,n,f); 094 095 if(ifenough(n,f)==0) 096 { 097 sort(f.begin(),f.end()); 098 for(int j=0;j<f.size();j++) 099 { 100 if(j!=f.size()-1) 101 cout<<f[j]<<"*"; 102 else 103 cout<<f[j]; 104 } 105 cout<<endl; 106 break; 107 } 108 } 109 } 110 int main() 111 { 112 int n; 113 cin>>n; 114 repeatRho(n); 115 }